#include "example.h"
#include "ui_example.h"
#include <QSerialPortInfo>
#include <QMessageBox>
#include <QTimer>
#include <QDateTime>
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
#include <QThread>

#include <QDebug>

#include <QDialog>
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QMessageBox>
#include <QInputDialog>

example::example(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::example)
{
    ui->setupUi(this);
    ui->logEdit->setReadOnly(true);

    // 全屏（覆盖任务栏）
//    showFullScreen();

    // 初始化串口
    serialPort = new QSerialPort(this);

    // 🔒 初始化时禁用所有测试按钮（无样式）
    ui->ddr_test->setEnabled(false);
    ui->emmc_test->setEnabled(false);
    ui->rtc_test->setEnabled(false);
    ui->wifi_test->setEnabled(false);
    ui->output1_test->setEnabled(false);
    ui->output2_test->setEnabled(false);
    ui->input1_test->setEnabled(false);
    ui->input2_test->setEnabled(false);
    ui->test1_422->setEnabled(false);
    ui->test2_422->setEnabled(false);
    ui->test1_485->setEnabled(false);
    ui->test2_485->setEnabled(false);
    ui->test3_485->setEnabled(false);
    ui->test4_485->setEnabled(false);
    ui->test1_eth->setEnabled(false);
    ui->test2_eth->setEnabled(false);
    ui->test3_eth->setEnabled(false);
    ui->test4_eth->setEnabled(false);
    ui->test5_eth->setEnabled(false);
    ui->test_4g->setEnabled(false);
    ui->usb_test->setEnabled(false);
    ui->mAoutput1_test->setEnabled(false);
    ui->mAoutput2_test->setEnabled(false);
    ui->mAin1_test->setEnabled(false);
    ui->mAin2_test->setEnabled(false);
    ui->hdd_test->setEnabled(false);
    ui->pb_test->setEnabled(false);  // ← 新增
    ui->led_test->setEnabled(false);  // ← 新增

    // 创建定时器并连接超时处理
    m_rtcTimeoutTimer = new QTimer(this);
    m_rtcTimeoutTimer->setSingleShot(true);
    connect(m_rtcTimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingForRtcResult) {
            m_waitingForRtcResult = false;
            m_rtcTestSuccess = false;
            updateStatus("RTC 测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("RTC 测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    m_ddrTimeoutTimer = new QTimer(this);
    m_ddrTimeoutTimer->setSingleShot(true);
    connect(m_ddrTimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingForDdrResult) {
            m_waitingForDdrResult = false;
            m_ddrTestSuccess = false;
            updateStatus("DDR 测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("DDR 测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    m_emmcTimeoutTimer = new QTimer(this);
    m_emmcTimeoutTimer->setSingleShot(true);
    connect(m_emmcTimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingForEmmcResult) {
            m_waitingForEmmcResult = false;
            m_emmcTestSuccess = false;
            updateStatus("eMMC 测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("eMMC 测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    m_wifiTimeoutTimer = new QTimer(this);
    m_wifiTimeoutTimer->setSingleShot(true);
    connect(m_wifiTimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingForWifiResult) {
            m_waitingForWifiResult = false;
            m_wifiTestSuccess = false;
            updateStatus("WiFi 测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("WiFi 测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    // GPIO Output1 超时定时器（可选，设为 5 秒）
    m_output1TimeoutTimer = new QTimer(this);
    m_output1TimeoutTimer->setSingleShot(true);
    connect(m_output1TimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingForOutput1Result) {
            m_waitingForOutput1Result = false;
            m_output1TestSuccess = false;
            updateStatus("GPIO 输出1 测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("GPIO 输出1 测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    // GPIO Output2 超时定时器（可选，设为 5 秒）
    m_output2TimeoutTimer = new QTimer(this);
    m_output2TimeoutTimer->setSingleShot(true);
    connect(m_output2TimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingForOutput2Result) {
            m_waitingForOutput2Result = false;
            m_output2TestSuccess = false;
            updateStatus("GPIO 输出2 测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("GPIO 输出2 测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    // GPIO input1 超时定时器（可选，设为 5 秒）
    m_input1TimeoutTimer = new QTimer(this);
    m_input1TimeoutTimer->setSingleShot(true);
    connect(m_input1TimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingForInput1Result) {
            m_waitingForInput1Result = false;
            m_input1TestSuccess = false;
            updateStatus("GPIO 输入1 测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("GPIO 输入1 测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    // GPIO input2 超时定时器（可选，设为 5 秒）
    m_input2TimeoutTimer = new QTimer(this);
    m_input2TimeoutTimer->setSingleShot(true);
    connect(m_input2TimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingForInput2Result) {
            m_waitingForInput2Result = false;
            m_input2TestSuccess = false;
            updateStatus("GPIO 输入2 测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("GPIO 输入2 测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    // 422-1 超时定时器
    m_422_1TimeoutTimer = new QTimer(this);
    m_422_1TimeoutTimer->setSingleShot(true);
    connect(m_422_1TimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingFor422_1Result) {
            m_waitingFor422_1Result = false;
            m_422_1TestSuccess = false;
            updateStatus("422-1 测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("422-1 测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    // 422-2 超时定时器
    m_422_2TimeoutTimer = new QTimer(this);
    m_422_2TimeoutTimer->setSingleShot(true);
    connect(m_422_2TimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingFor422_2Result) {
            m_waitingFor422_2Result = false;
            m_422_2TestSuccess = false;
            updateStatus("422-2 测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("422-2 测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    // 485-1 超时定时器
    m_485_1TimeoutTimer = new QTimer(this);
    m_485_1TimeoutTimer->setSingleShot(true);
    connect(m_485_1TimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingFor485_1Result) {
            m_waitingFor485_1Result = false;
            m_485_1TestSuccess = false;
            updateStatus("485-1 测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("485-1 测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    // 485-2 超时定时器
    m_485_2TimeoutTimer = new QTimer(this);
    m_485_2TimeoutTimer->setSingleShot(true);
    connect(m_485_2TimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingFor485_2Result) {
            m_waitingFor485_2Result = false;
            m_485_2TestSuccess = false;
            updateStatus("485-2 测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("485-2 测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    // 485-3 超时定时器
    m_485_3TimeoutTimer = new QTimer(this);
    m_485_3TimeoutTimer->setSingleShot(true);
    connect(m_485_3TimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingFor485_3Result) {
            m_waitingFor485_3Result = false;
            m_485_3TestSuccess = false;
            updateStatus("485-3 测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("485-3 测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    // 485-4 超时定时器
    m_485_4TimeoutTimer = new QTimer(this);
    m_485_4TimeoutTimer->setSingleShot(true);
    connect(m_485_4TimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingFor485_4Result) {
            m_waitingFor485_4Result = false;
            m_485_4TestSuccess = false;
            updateStatus("485-4 测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("485-4 测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    // ===== Ethernet Test Timeout Timers =====
    m_eth1TimeoutTimer = new QTimer(this);
    m_eth1TimeoutTimer->setSingleShot(true);
    connect(m_eth1TimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingForEth1Result) {
            m_waitingForEth1Result = false;
            m_eth1TestSuccess = false;
            updateStatus("网口1测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("网口1测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    m_eth2TimeoutTimer = new QTimer(this);
    m_eth2TimeoutTimer->setSingleShot(true);
    connect(m_eth2TimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingForEth2Result) {
            m_waitingForEth2Result = false;
            m_eth2TestSuccess = false;
            updateStatus("网口2测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("网口2测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    m_eth3TimeoutTimer = new QTimer(this);
    m_eth3TimeoutTimer->setSingleShot(true);
    connect(m_eth3TimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingForEth3Result) {
            m_waitingForEth3Result = false;
            m_eth3TestSuccess = false;
            updateStatus("网口3测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("网口3测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    m_eth4TimeoutTimer = new QTimer(this);
    m_eth4TimeoutTimer->setSingleShot(true);
    connect(m_eth4TimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingForEth4Result) {
            m_waitingForEth4Result = false;
            m_eth4TestSuccess = false;
            updateStatus("网口4测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("网口4测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    m_eth5TimeoutTimer = new QTimer(this);
    m_eth5TimeoutTimer->setSingleShot(true);
    connect(m_eth5TimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingForEth5Result) {
            m_waitingForEth5Result = false;
            m_eth5TestSuccess = false;
            updateStatus("网口5测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("网口5测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    // ===== 4G Test Timeout Timer =====
    m_4gTimeoutTimer = new QTimer(this);
    m_4gTimeoutTimer->setSingleShot(true);
    connect(m_4gTimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingFor4gResult) {
            m_waitingFor4gResult = false;
            m_4gTestSuccess = false;
            updateStatus("4G测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("4G测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    // ===== USB Test Timeout Timer =====
    m_usbTimeoutTimer = new QTimer(this);
    m_usbTimeoutTimer->setSingleShot(true);
    connect(m_usbTimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingForUsbResult) {
            m_waitingForUsbResult = false;
            m_usbTestSuccess = false;
            updateStatus("USB测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("USB测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });


    //4-20mA in
    // example.cpp 构造函数中

    m_mAIn1TimeoutTimer = new QTimer(this);
    m_mAIn1TimeoutTimer->setSingleShot(true);
    connect(m_mAIn1TimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingFormAIn1Result) {
            m_waitingFormAIn1Result = false;
            m_mAIn1TestSuccess = false; // 明确标记失败
            updateStatus("4-20mA输入1测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("4-20mA输入1测试: 超时", false);
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    m_mAIn2TimeoutTimer = new QTimer(this);
    m_mAIn2TimeoutTimer->setSingleShot(true);
    connect(m_mAIn2TimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingFormAIn2Result) {
            m_waitingFormAIn2Result = false;
            m_mAIn2TestSuccess = false; // 明确标记失败
            updateStatus("4-20mA输入2测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("4-20mA输入2测试: 超时", false);
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    // 在 mAIn1/mAIn2 定时器之后添加：
    m_hddTimeoutTimer = new QTimer(this);
    m_hddTimeoutTimer->setSingleShot(true);
    connect(m_hddTimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingForHddResult) {
            m_waitingForHddResult = false;
            m_hddTestSuccess = false;
            updateStatus("HDD测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("HDD测试: 超时", false);
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });

    // 在其他定时器（如 eth1）之后添加：
    m_pbTimeoutTimer = new QTimer(this);
    m_pbTimeoutTimer->setSingleShot(true);
    connect(m_pbTimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitingForPbResult) {
            m_waitingForPbResult = false;
            m_pbTestSuccess = false;
            updateStatus("光口测试: 超时 ❌", example::TestStatus::Failed);
            appendLog("光口测试: 超时", false);
            m_recvBuffer.clear();
            sendCtrlCAndDelay(300);
            updateTestButtonsStyle();
        }
    });



    // 串口接收
    connect(serialPort, &QSerialPort::readyRead, this, &example::serialPortReadyRead_Solt);

    // 刷新串口
    on_refreshBt_clicked();
}

example::~example()
{
    if (serialPort->isOpen()) {
        serialPort->close();
    }
    delete serialPort;
    delete ui;
}

void example::handleTestResult(
    bool& waitingFlag,
    bool& successFlag,
    QTimer* timeoutTimer,
    const QString& testName,
    const char* successKeyword,
    const char* failKeyword)
{
    if (!waitingFlag) return;

    if (m_recvBuffer.contains(successKeyword)) {
        if (timeoutTimer) timeoutTimer->stop();
        waitingFlag = false;
        successFlag = true;
        updateStatus(testName + ": 成功 ✅", example::TestStatus::Success);
        appendLog(testName + ": 成功", true);
        m_recvBuffer.clear();
        sendCtrlCAndDelay(300);
        updateTestButtonsStyle();
    }
    else if (m_recvBuffer.contains(failKeyword)) {
        if (timeoutTimer) timeoutTimer->stop();
        waitingFlag = false;
        successFlag = false;
        updateStatus(testName + ": 失败 ❌", example::TestStatus::Failed);
        appendLog(testName + ": 失败", false);
        m_recvBuffer.clear();
        sendCtrlCAndDelay(300);
        updateTestButtonsStyle();
    }
}

void example::handleUserTestResult(
    bool& waitingFlag,
    bool& successFlag,
    QTimer* timeoutTimer,
    const QString& testName,
    const char* successKeyword,
    const char* failKeyword)
{
    if (!waitingFlag) return;

    if (m_recvBuffer.contains(successKeyword)) {
        if (timeoutTimer) timeoutTimer->stop();
        if (m_userTimeoutTimer) m_userTimeoutTimer->stop();
        if (m_waitDialog) {
            m_waitDialog->deleteLater();
            m_waitDialog = nullptr;
        }
        waitingFlag = false;
        successFlag = true;
        updateStatus(testName + ": 成功 ✅", example::TestStatus::Success);
        appendLog(testName + ": 成功", true);
        m_recvBuffer.clear();
        sendCtrlCAndDelay(300);
        updateTestButtonsStyle();
    }
    else if (m_recvBuffer.contains(failKeyword)) {
        if (timeoutTimer) timeoutTimer->stop();
        if (m_userTimeoutTimer) m_userTimeoutTimer->stop();
        if (m_waitDialog) {
            m_waitDialog->deleteLater();
            m_waitDialog = nullptr;
        }
        waitingFlag = false;
        successFlag = false;
        updateStatus(testName + ": 失败 ❌", example::TestStatus::Failed);
        appendLog(testName + ": 失败", false);
        m_recvBuffer.clear();
        sendCtrlCAndDelay(300);
        updateTestButtonsStyle();
    }
}

void example::handleSimpleTestResult(
    bool& waitingFlag,
    bool& successFlag,
    QTimer* timeoutTimer,
    const QString& testName,
    const char* successKeyword,
    const char* failKeyword)
{
    if (!waitingFlag) return;

    if (m_recvBuffer.contains(successKeyword)) {
        if (timeoutTimer) timeoutTimer->stop();
        waitingFlag = false;
        successFlag = true;
        updateStatus(testName + ": 成功 ✅", example::TestStatus::Success);
        appendLog(testName + "成功！", true);
        updateTestButtonsStyle();
    }
    else if (m_recvBuffer.contains(failKeyword)) {
        if (timeoutTimer) timeoutTimer->stop();
        waitingFlag = false;
        successFlag = false;
        updateStatus(testName + ": 失败 ❌", example::TestStatus::Failed);
        appendLog(testName + "失败！", false);
        updateTestButtonsStyle();
    }
}

void example::serialPortReadyRead_Solt()
{
    QByteArray data = serialPort->readAll();
    if (data.isEmpty()) return;

    // ✅ 新增：如果正在等待汇总结果，只缓存，不显示到 recvEdit
    if (m_waitingForSummaryResult) {
        m_summaryBuffer += QString::fromUtf8(data);
        return; // 不执行后续任何测试结果解析
    }

    // ✅ 新增：如果正在等待“显示报告”响应，只缓存，不显示到 recvEdit
    if (m_waitingForShowReport) {
        m_showReportBuffer += QString::fromUtf8(data);
        return; // 跳过所有其他处理
    }

    ui->recvEdit->appendPlainText(QString::fromUtf8(data));
    m_recvBuffer += data;

    // 🔁 检测系统初始化成功（出现 shell 提示符）
    if (m_waitingForInitSuccess) {
        QString bufferStr = QString::fromUtf8(m_recvBuffer);
        if (bufferStr.contains(QRegExp("[#\\$]\\s*$"))) {
            m_waitingForInitSuccess = false;
            updateStatus("系统初始化: 成功 ✅", example::TestStatus::Success);
            appendLog("系统初始化: 登录成功，已进入终端", true);
            m_recvBuffer.clear();
            updateTestButtonsStyle();
        }
    }

    // === 统一处理自动测试项 ===
    handleTestResult(
        m_waitingForDdrResult, m_ddrTestSuccess, m_ddrTimeoutTimer,
        "DDR 测试", "DDR 测试成功", "DDR 测试失败"
    );

    handleTestResult(
        m_waitingForEmmcResult, m_emmcTestSuccess, m_emmcTimeoutTimer,
        "eMMC 测试", "emmc 测试成功", "emmc 测试失败"
    );

    handleTestResult(
        m_waitingForRtcResult, m_rtcTestSuccess, m_rtcTimeoutTimer,
        "RTC 测试", "RTC 测试成功", "RTC 测试失败"
    );

    handleTestResult(
        m_waitingForWifiResult, m_wifiTestSuccess, m_wifiTimeoutTimer,
        "WiFi 测试", "wifi 测试成功", "wifi 测试失败"
    );

    // ===== 处理 4G 测试结果（自动，无用户交互）=====
    handleTestResult(
        m_waitingFor4gResult, m_4gTestSuccess, m_4gTimeoutTimer,
        "4G测试", "4G网络测试成功", "4G网络测试失败"
    );

    // ===== 处理 4-20mA 输入测试结果 =====
    handleUserTestResult(
        m_waitingFormAIn1Result, m_mAIn1TestSuccess, m_mAIn1TimeoutTimer,
        "4-20mA输入1测试", "4-20mA输入1测试成功", "4-20mA输入1测试失败"
    );

    handleUserTestResult(
        m_waitingFormAIn2Result, m_mAIn2TestSuccess, m_mAIn2TimeoutTimer,
        "4-20mA输入2测试", "4-20mA输入2测试成功", "4-20mA输入2测试失败"
    );

    // ===== 处理 HDD 测试结果 =====
    handleUserTestResult(
        m_waitingForHddResult, m_hddTestSuccess, m_hddTimeoutTimer,
        "HDD测试", "磁盘挂载成功", "磁盘挂载失败"
    );

    // ===== 处理光口测试结果 =====
    handleUserTestResult(
        m_waitingForPbResult, m_pbTestSuccess, m_pbTimeoutTimer,
        "光口测试", "光口测试成功", "光口测试失败"
    );

    // 在 serialPortReadyRead_Solt() 的 handle* 调用区域末尾添加：
    handleUserTestResult(
        m_waitingForSnWrite,
        m_snWriteSuccess,
        m_snWriteTimeoutTimer,
        "SN写入",
        "SN号写入成功",
        "SN号写入失败"
    );

    handleUserTestResult(
        m_waitingForSn1Write,
        m_snWrite1Success,
        m_snWrite1TimeoutTimer,
        "SN写入",
        "SN号写入成功",
        "SN号写入失败"
    );

    // ===== 处理 USB 测试结果 =====
    handleTestResult(
        m_waitingForUsbResult, m_usbTestSuccess, m_usbTimeoutTimer,
        "USB测试", "usbhost 测试成功", "usbhost 测试失败"
    );

    // === 处理 RS485 / RS422 系列（带用户弹窗）===
    // handleUserTestResult(
    //     m_waitingFor485_1Result, m_485_1TestSuccess, m_485_1TimeoutTimer,
    //     "485-1 测试", "485-1 测试成功", "485-1 测试失败"
    // );

    // handleUserTestResult(
    //     m_waitingFor485_2Result, m_485_2TestSuccess, m_485_2TimeoutTimer,
    //     "485-2 测试", "485-2 测试成功", "485-2 测试失败"
    // );

    // handleUserTestResult(
    //     m_waitingFor485_3Result, m_485_3TestSuccess, m_485_3TimeoutTimer,
    //     "485-3 测试", "485-3 测试成功", "485-3 测试失败"
    // );

    // handleUserTestResult(
    //     m_waitingFor485_4Result, m_485_4TestSuccess, m_485_4TimeoutTimer,
    //     "485-4 测试", "485-4 测试成功", "485-4 测试失败"
    // );

    // handleUserTestResult(
    //     m_waitingFor422_1Result, m_422_1TestSuccess, m_422_1TimeoutTimer,
    //     "422-1 测试", "422-1 测试成功", "422-1 测试失败"
    // );

    // handleUserTestResult(
    //     m_waitingFor422_2Result, m_422_2TestSuccess, m_422_2TimeoutTimer,
    //     "422-2 测试", "422-2 测试成功", "422-2 测试失败"
    // );

    // ===== 处理网口测试结果 =====
    handleUserTestResult(
        m_waitingForEth1Result, m_eth1TestSuccess, m_eth1TimeoutTimer,
        "网口1测试", "网口1测试成功", "网口1测试失败"
    );
    handleUserTestResult(
        m_waitingForEth2Result, m_eth2TestSuccess, m_eth2TimeoutTimer,
        "网口2测试", "网口2测试成功", "网口2测试失败"
    );
    handleUserTestResult(
        m_waitingForEth3Result, m_eth3TestSuccess, m_eth3TimeoutTimer,
        "网口3测试", "网口3测试成功", "网口3测试失败"
    );
    handleUserTestResult(
        m_waitingForEth4Result, m_eth4TestSuccess, m_eth4TimeoutTimer,
        "网口4测试", "网口4测试成功", "网口4测试失败"
    );
    handleUserTestResult(
        m_waitingForEth5Result, m_eth5TestSuccess, m_eth5TimeoutTimer,
        "网口5测试", "网口5测试成功", "网口5测试失败"
    );

    // === 手动 GPIO 测试（仅记录回显）=== mA 测试是人工判断，不需要等设备回显,而且 mAgpio_out_1.sh 是你发送的内容-建议删除这两行，避免误导
    if (m_waitingForOutput1Result && m_recvBuffer.contains("gpio_out_1.sh")) {
        appendLog("GPIO Output1: 收到设备回显", true);
    }

    if (m_waitingForOutput2Result && m_recvBuffer.contains("gpio_out_2.sh")) {
        appendLog("GPIO Output2: 收到设备回显", true);
    }

    // === 手动 ma_GPIO 测试（仅记录回显）===
    if (m_waitingFormaOutput1Result && m_recvBuffer.contains("mAgpio_out_1.sh")) {
        appendLog("maGPIO Output1: 收到设备回显", true);
    }

    if (m_waitingFormaOutput1Result && m_recvBuffer.contains("mAgpio_out_2.sh")) {
        appendLog("maGPIO Output2: 收到设备回显", true);
    }

    // === 干接点输入测试 ===
    handleSimpleTestResult(
        m_waitingForInput1Result, m_input1TestSuccess, m_input1TimeoutTimer,
        "干接点-1输入测试", "干接点-1输入成功", "干接点-1输入失败"
    );

    handleSimpleTestResult(
        m_waitingForInput2Result, m_input2TestSuccess, m_input2TimeoutTimer,
        "干接点-2输入测试", "干接点-2输入成功", "干接点-2输入失败"
    );
    // ========== 检测“测试成功”并触发人工确认 ==========
    if (m_waitingFor485_1Result && m_recvBuffer.contains("485-1 测试成功")) {
        m_waitingFor485_1Result = false;
        promptUserForResult(m_485_1TestSuccess, "485-1 测试");
    }
    else if (m_waitingFor485_2Result && m_recvBuffer.contains("485-2 测试成功")) {
        m_waitingFor485_2Result = false;
        promptUserForResult(m_485_2TestSuccess, "485-2 测试");
    }
    else if (m_waitingFor485_3Result && m_recvBuffer.contains("485-3 测试成功")) {
        m_waitingFor485_3Result = false;
        promptUserForResult(m_485_3TestSuccess, "485-3 测试");
    }
    else if (m_waitingFor485_4Result && m_recvBuffer.contains("485-4 测试成功")) {
        m_waitingFor485_4Result = false;
        promptUserForResult(m_485_4TestSuccess, "485-4 测试");
    }
    else if (m_waitingFor422_1Result && m_recvBuffer.contains("422-1 测试成功")) {
        m_waitingFor422_1Result = false;
        promptUserForResult(m_422_1TestSuccess, "422-1 测试");
    }
    else if (m_waitingFor422_2Result && m_recvBuffer.contains("422-2 测试成功")) {
        m_waitingFor422_2Result = false;
        promptUserForResult(m_422_2TestSuccess, "422-2 测试");
    }
}

// 其他 UI 槽函数（openBt, closeBt 等）保持不变...
void example::on_openBt_clicked()
{
    if (serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口已打开，请先关闭");
        on_refreshBt_clicked();
        return;
    }

    QString portName = ui->serialCb->currentText().split(" ").first();
    if (portName.isEmpty()) {
        QMessageBox::critical(this, "错误", "请选择有效的串口设备");
        on_refreshBt_clicked();
        return;
    }

    QSerialPort::BaudRate baudRate = QSerialPort::Baud115200;
    QSerialPort::DataBits dataBits = QSerialPort::Data8;
    QSerialPort::StopBits stopBits = QSerialPort::OneStop;
    QSerialPort::Parity parity = QSerialPort::NoParity;

    QString brStr = ui->baundrateCb->currentText();
    if (brStr == "4800") baudRate = QSerialPort::Baud4800;
    else if (brStr == "9600") baudRate = QSerialPort::Baud9600;
    else if (brStr == "115200") baudRate = QSerialPort::Baud115200;
//    else if (brStr == "1500000") baudRate = QSerialPort::Baud1500000;
    else {
        QMessageBox::warning(this, "警告", "不支持的波特率：" + brStr);
        return;
    }

    QString dbStr = ui->dataCb->currentText();
    if (dbStr == "5") dataBits = QSerialPort::Data5;
    else if (dbStr == "6") dataBits = QSerialPort::Data6;
    else if (dbStr == "7") dataBits = QSerialPort::Data7;
    else if (dbStr == "8") dataBits = QSerialPort::Data8;
    else {
        QMessageBox::warning(this, "警告", "不支持的数据位：" + dbStr);
        return;
    }

    QString sbStr = ui->stopCb->currentText();
    if (sbStr == "1") stopBits = QSerialPort::OneStop;
    else if (sbStr == "1.5") stopBits = QSerialPort::OneAndHalfStop;
    else if (sbStr == "2") stopBits = QSerialPort::TwoStop;
    else {
        QMessageBox::warning(this, "警告", "不支持的停止位：" + sbStr);
        return;
    }

    QString pbStr = ui->checkCb->currentText();
    if (pbStr == "none") parity = QSerialPort::NoParity;
    else if (pbStr == "even") parity = QSerialPort::EvenParity;
    else if (pbStr == "odd") parity = QSerialPort::OddParity;
    else if (pbStr == "mark") parity = QSerialPort::MarkParity;
    else if (pbStr == "space") parity = QSerialPort::SpaceParity;
    else {
        QMessageBox::warning(this, "警告", "不支持的校验位：" + pbStr);
        return;
    }

    serialPort->setPortName(portName);
    serialPort->setBaudRate(baudRate);
    serialPort->setDataBits(dataBits);
    serialPort->setStopBits(stopBits);
    serialPort->setParity(parity);

    if (serialPort->open(QIODevice::ReadWrite)) {
        QMessageBox::information(this, "成功", "串口打开成功！");
    } else {
        QMessageBox::critical(this, "失败", "无法打开串口:\n" + serialPort->errorString());
    }
}

void example::on_closeBt_clicked()
{
    if (serialPort->isOpen()) {
        serialPort->close();
        QMessageBox::information(this, "提示", "串口已关闭");
    } else {
        QMessageBox::information(this, "提示", "串口未打开");
    }
}

void example::on_sendBt_clicked()
{
    QString text = ui->sendEdit->text().trimmed();
    if (!text.isEmpty()) {
        serialPort->write(text.toUtf8());
        ui->recvEdit->appendPlainText("发送: " + text);
        ui->sendEdit->clear();
    }
}

void example::on_clearBt_clicked()
{
    ui->recvEdit->clear();
}

void example::on_refreshBt_clicked()
{
    ui->serialCb->clear();
    bool hasPorts = false;
    for (const QSerialPortInfo &info : QSerialPortInfo::availablePorts()) {
        ui->serialCb->addItem(info.portName());
        hasPorts = true;
    }
    if (!hasPorts) {
        ui->serialCb->addItem("无可用串口");
    }
}

void example::appendLog(const QString &msg, bool success)
{
    QString time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    QString color = success ? "green" : "red";
    QString logEntry = QString("[%1] %2").arg(time, msg);
    QString html = QString("<font color='%1'>%2</font><br>")
                       .arg(color, logEntry.toHtmlEscaped());
    ui->logEdit->insertHtml(html);
    ui->logEdit->ensureCursorVisible();
}


void example::updateStatus(const QString &msg, TestStatus status)
{
    ui->statusLabel->setText(msg);

    QString style;
    switch (status) {
    case TestStatus::Running:
        style = "color: orange; font-weight: bold; font-size: 20px;"; // 或 yellow  orange
        break;
    case TestStatus::Success:
        style = "color: green; font-weight: bold; font-size: 20px;";
        break;
    case TestStatus::Failed:
        style = "color: red; font-weight: bold; font-size: 20px;";
        break;
    }
    ui->statusLabel->setStyleSheet(style);
}

// ------------------- 测试功能实现 -------------------

void example::on_init_test_clicked()
{
    ui->init_test->setEnabled(false);
    QTimer::singleShot(5000, this, [this]() {
        ui->init_test->setEnabled(true);
    });

    if (!serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开，无法执行系统初始化！");
        return;
    }

    QMessageBox::information(this, "系统初始化",
        "即将发送:\n\n"
        "  用户名: root\n"
        "  密码: hanweiai\n"
        "  命令: cd /userfs\n\n"
        "请确保设备已启动并处于登录界面。\n"
        "点击 OK 开始初始化。",
        QMessageBox::Ok);

    // 🔁 关键：重置所有测试状态和按钮颜色
    resetAllTestStates();

    serialPort->clear();
    m_recvBuffer.clear();
    m_waitingForInitSuccess = true;

    QTimer::singleShot(500, this, [this]() {
        serialPort->write("root\n");
        ui->recvEdit->appendPlainText("[发送] root");
        QTimer::singleShot(800, this, [this]() {
            serialPort->write("hanweiai\n");
            ui->recvEdit->appendPlainText("[发送] hanweiai (密码)");
            QTimer::singleShot(800, this, [this]() {
                serialPort->write("cd /userfs\n");
                ui->recvEdit->appendPlainText("[发送] cd /userfs");
                QTimer::singleShot(500, this, [this]() {
                    serialPort->write("ls\n");
                    ui->recvEdit->appendPlainText("[发送] ls");
                });
            });
        });
    });

    updateStatus("系统初始化: 执行中...", example::TestStatus::Running);
    appendLog("系统初始化: 已发送登录指令", true);
}

// ✅ 核心函数：统一管理按钮颜色和状态
void example::updateTestButtonsStyle()
{
    bool initSuccess = !m_waitingForInitSuccess;

    // DDR
    if (m_waitingForDdrResult) {
        ui->ddr_test->setEnabled(true);
        ui->ddr_test->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingForDdrResult) {
        ui->ddr_test->setEnabled(true);
        ui->ddr_test->setStyleSheet(
            m_ddrTestSuccess ? "background: green; color: white;" :
            m_ddrTestSuccess == false && !m_waitingForDdrResult ? "background: red; color: white;" :
            "background: blue; color: white;"
        );
    } else {
        ui->ddr_test->setEnabled(false);
        ui->ddr_test->setStyleSheet("");
    }

    // eMMC
    if (m_waitingForEmmcResult) {
        ui->emmc_test->setEnabled(true);
        ui->emmc_test->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingForEmmcResult) {
        ui->emmc_test->setEnabled(true);
        ui->emmc_test->setStyleSheet(
            m_emmcTestSuccess ? "background: green; color: white;" :
            m_emmcTestSuccess == false && !m_waitingForEmmcResult ? "background: red; color: white;" :
            "background: blue; color: white;"
        );
    } else {
        ui->emmc_test->setEnabled(false);
        ui->emmc_test->setStyleSheet("");
    }

    // RTC
    if (m_waitingForRtcResult) {
        ui->rtc_test->setEnabled(true);
        ui->rtc_test->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingForRtcResult) {
        ui->rtc_test->setEnabled(true);
        ui->rtc_test->setStyleSheet(
            m_rtcTestSuccess ? "background: green; color: white;" :
            m_rtcTestSuccess == false && !m_waitingForRtcResult ? "background: red; color: white;" :
            "background: blue; color: white;"
        );
    } else {
        ui->rtc_test->setEnabled(false);
        ui->rtc_test->setStyleSheet("");
    }

    // WiFi
    if (m_waitingForWifiResult) {
        ui->wifi_test->setEnabled(true);
        ui->wifi_test->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingForWifiResult) {
        ui->wifi_test->setEnabled(true);
        ui->wifi_test->setStyleSheet(
            m_wifiTestSuccess ? "background: green; color: white;" :
            m_wifiTestSuccess == false && !m_waitingForWifiResult ? "background: red; color: white;" :
            "background: blue; color: white;"
        );
    } else {
        ui->wifi_test->setEnabled(false);
        ui->wifi_test->setStyleSheet("");
    }

    // GPIO Output1
    if (m_waitingForOutput1Result) {
        ui->output1_test->setEnabled(true);
        ui->output1_test->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingForOutput1Result) {
        ui->output1_test->setEnabled(true);
        ui->output1_test->setStyleSheet(
            m_output1TestSuccess ? "background: green; color: white;" :
            m_output1TestSuccess == false && !m_waitingForOutput1Result ? "background: red; color: white;" :
            "background: blue; color: white;"
        );
    } else {
        ui->output1_test->setEnabled(false);
        ui->output1_test->setStyleSheet("");
    }

    // GPIO Output2
    if (m_waitingForOutput2Result) {
        ui->output2_test->setEnabled(true);
        ui->output2_test->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingForOutput2Result) {
        ui->output2_test->setEnabled(true);
        ui->output2_test->setStyleSheet(
            m_output2TestSuccess ? "background: green; color: white;" :
            m_output2TestSuccess == false && !m_waitingForOutput2Result ? "background: red; color: white;" :
            "background: blue; color: white;"
        );
    } else {
        ui->output2_test->setEnabled(false);
        ui->output2_test->setStyleSheet("");
    }

    // GPIO input1
    if (m_waitingForInput1Result) {
        ui->input1_test->setEnabled(true);
        ui->input1_test->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingForInput1Result) {
        ui->input1_test->setEnabled(true);
        ui->input1_test->setStyleSheet(
            m_input1TestSuccess ? "background: green; color: white;" :
            m_input1TestSuccess == false && !m_waitingForInput1Result ? "background: red; color: white;" :
            "background: blue; color: white;"
        );
    } else {
        ui->input1_test->setEnabled(false);
        ui->input1_test->setStyleSheet("");
    }

    // GPIO input2
    if (m_waitingForInput2Result) {
        ui->input2_test->setEnabled(true);
        ui->input2_test->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingForInput2Result) {
        ui->input2_test->setEnabled(true);
        ui->input2_test->setStyleSheet(
            m_input2TestSuccess ? "background: green; color: white;" :
            m_input2TestSuccess == false && !m_waitingForInput2Result ? "background: red; color: white;" :
            "background: blue; color: white;"
        );
    } else {
        ui->input2_test->setEnabled(false);
        ui->input2_test->setStyleSheet("");
    }

    // 422-1
    QPushButton *test422Btn = ui->test1_422; // 假设对象名为 test1_422
    if (m_waitingFor422_1Result) {
        test422Btn->setEnabled(true);
        test422Btn->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingFor422_1Result) {
        test422Btn->setEnabled(true);
        test422Btn->setStyleSheet(
            m_422_1TestSuccess ? "background: green; color: white;" :
            m_422_1TestSuccess == false && !m_waitingFor422_1Result ? "background: red; color: white;" :
            "background: blue; color: white;"
        );
    } else {
        test422Btn->setEnabled(false);
        test422Btn->setStyleSheet("");
    }

    // 422-2
    QPushButton *test422_2Btn = ui->test2_422; // 假设 UI 对象名为 test2_422
    if (m_waitingFor422_2Result) {
        test422_2Btn->setEnabled(true);
        test422_2Btn->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingFor422_2Result) {
        test422_2Btn->setEnabled(true);
        test422_2Btn->setStyleSheet(
            m_422_2TestSuccess ? "background: green; color: white;" :
            m_422_2TestSuccess == false && !m_waitingFor422_2Result ? "background: red; color: white;" :
            "background: blue; color: white;"
        );
    } else {
        test422_2Btn->setEnabled(false);
        test422_2Btn->setStyleSheet("");
    }

    // 485-1
    if (m_waitingFor485_1Result) {
        ui->test1_485->setEnabled(true);
        ui->test1_485->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingFor485_1Result) {
        ui->test1_485->setEnabled(true);
        ui->test1_485->setStyleSheet(
            m_485_1TestSuccess ? "background: green; color: white;" :
            m_485_1TestSuccess == false && !m_waitingFor485_1Result ? "background: red; color: white;" :
            "background: blue; color: white;"
        );
    } else {
        ui->test1_485->setEnabled(false);
        ui->test1_485->setStyleSheet("");
    }

    // 485-2
    if (m_waitingFor485_2Result) {
        ui->test2_485->setEnabled(true);
        ui->test2_485->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingFor485_2Result) {
        ui->test2_485->setEnabled(true);
        ui->test2_485->setStyleSheet(
            m_485_2TestSuccess ? "background: green; color: white;" :
            m_485_2TestSuccess == false && !m_waitingFor485_2Result ? "background: red; color: white;" :
            "background: blue; color: white;"
        );
    } else {
        ui->test2_485->setEnabled(false);
        ui->test2_485->setStyleSheet("");
    }

    // 485-3
    if (m_waitingFor485_3Result) {
        ui->test3_485->setEnabled(true);
        ui->test3_485->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingFor485_3Result) {
        ui->test3_485->setEnabled(true);
        ui->test3_485->setStyleSheet(
            m_485_3TestSuccess ? "background: green; color: white;" :
            m_485_3TestSuccess == false && !m_waitingFor485_3Result ? "background: red; color: white;" :
            "background: blue; color: white;"
        );
    } else {
        ui->test3_485->setEnabled(false);
        ui->test3_485->setStyleSheet("");
    }

    // 485-4
    if (m_waitingFor485_4Result) {
        ui->test4_485->setEnabled(true);
        ui->test4_485->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingFor485_4Result) {
        ui->test4_485->setEnabled(true);
        ui->test4_485->setStyleSheet(
            m_485_4TestSuccess ? "background: green; color: white;" :
            m_485_4TestSuccess == false && !m_waitingFor485_4Result ? "background: red; color: white;" :
            "background: blue; color: white;"
        );
    } else {
        ui->test4_485->setEnabled(false);
        ui->test4_485->setStyleSheet("");
    }

    // ===== Ethernet 1 =====
    if (m_waitingForEth1Result) {
        ui->test1_eth->setEnabled(true);
        ui->test1_eth->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingForEth1Result) {
        ui->test1_eth->setEnabled(true);
        ui->test1_eth->setStyleSheet(
            m_eth1TestSuccess ? "background: green; color: white;" :
            "background: red; color: white;"
        );
    } else {
        ui->test1_eth->setEnabled(false);
        ui->test1_eth->setStyleSheet("");
    }

    // ===== Ethernet 2 =====
    if (m_waitingForEth2Result) {
        ui->test2_eth->setEnabled(true);
        ui->test2_eth->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingForEth2Result) {
        ui->test2_eth->setEnabled(true);
        ui->test2_eth->setStyleSheet(
            m_eth2TestSuccess ? "background: green; color: white;" :
            "background: red; color: white;"
        );
    } else {
        ui->test2_eth->setEnabled(false);
        ui->test2_eth->setStyleSheet("");
    }

    // ===== Ethernet 3 =====
    if (m_waitingForEth3Result) {
        ui->test3_eth->setEnabled(true);
        ui->test3_eth->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingForEth3Result) {
        ui->test3_eth->setEnabled(true);
        ui->test3_eth->setStyleSheet(
            m_eth3TestSuccess ? "background: green; color: white;" :
            "background: red; color: white;"
        );
    } else {
        ui->test3_eth->setEnabled(false);
        ui->test3_eth->setStyleSheet("");
    }

    // ===== Ethernet 4 =====
    if (m_waitingForEth4Result) {
        ui->test4_eth->setEnabled(true);
        ui->test4_eth->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingForEth4Result) {
        ui->test4_eth->setEnabled(true);
        ui->test4_eth->setStyleSheet(
            m_eth4TestSuccess ? "background: green; color: white;" :
            "background: red; color: white;"
        );
    } else {
        ui->test4_eth->setEnabled(false);
        ui->test4_eth->setStyleSheet("");
    }

    // ===== Ethernet 5 =====
    if (m_waitingForEth5Result) {
        ui->test5_eth->setEnabled(true);
        ui->test5_eth->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingForEth5Result) {
        ui->test5_eth->setEnabled(true);
        ui->test5_eth->setStyleSheet(
            m_eth5TestSuccess ? "background: green; color: white;" :
            "background: red; color: white;"
        );
    } else {
        ui->test5_eth->setEnabled(false);
        ui->test5_eth->setStyleSheet("");
    }

    // ===== 4G Test Button =====
    if (m_waitingFor4gResult) {
        ui->test_4g->setEnabled(true);
        ui->test_4g->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingFor4gResult) {
        ui->test_4g->setEnabled(true);
        ui->test_4g->setStyleSheet(
            m_4gTestSuccess ? "background: green; color: white;" :
            "background: red; color: white;"
        );
    } else {
        ui->test_4g->setEnabled(false);
        ui->test_4g->setStyleSheet("");
    }

    // ===== USB Test Button =====
    if (m_waitingForUsbResult) {
        ui->usb_test->setEnabled(true);
        ui->usb_test->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingForUsbResult) {
        ui->usb_test->setEnabled(true);
        ui->usb_test->setStyleSheet(
            m_usbTestSuccess ? "background: green; color: white;" :
                               "background: red; color: white;"
        );
    } else {
        ui->usb_test->setEnabled(false);
        ui->usb_test->setStyleSheet("");
    }

    // maGPIO Output1
    if (m_waitingFormaOutput1Result) {
        ui->mAoutput1_test->setEnabled(true);
        ui->mAoutput1_test->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingFormaOutput1Result) {
        ui->mAoutput1_test->setEnabled(true);
        ui->mAoutput1_test->setStyleSheet(
            m_mAoutput1TestSuccess ? "background: green; color: white;" :
            m_mAoutput1TestSuccess == false && !m_waitingFormaOutput1Result ? "background: red; color: white;" :
            "background: blue; color: white;"
        );
    } else {
        ui->mAoutput1_test->setEnabled(false);
        ui->mAoutput1_test->setStyleSheet("");
    }

    // maGPIO Output2
    if (m_waitingFormaOutput2Result) {
        ui->mAoutput2_test->setEnabled(true);
        ui->mAoutput2_test->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingFormaOutput2Result) {
        ui->mAoutput2_test->setEnabled(true);
        ui->mAoutput2_test->setStyleSheet(
            m_mAoutput2TestSuccess ? "background: green; color: white;" :
            m_mAoutput2TestSuccess == false && !m_waitingFormaOutput2Result ? "background: red; color: white;" :
            "background: blue; color: white;"
        );
    } else {
        ui->mAoutput2_test->setEnabled(false);
        ui->mAoutput2_test->setStyleSheet("");
    }

    // maGPIO in1
    if (m_waitingFormAIn1Result) {
        ui->mAin1_test->setEnabled(true);
        ui->mAin1_test->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingFormAIn1Result) {
        ui->mAin1_test->setEnabled(true);
        ui->mAin1_test->setStyleSheet(
            m_mAIn1TestSuccess ? "background: green; color: white;" :
            m_mAIn1TestSuccess == false && !m_waitingFormAIn1Result ? "background: red; color: white;" :
            "background: blue; color: white;"
        );
    } else {
        ui->mAin1_test->setEnabled(false);
        ui->mAin1_test->setStyleSheet("");
    }

    // maGPIO in2
    if (m_waitingFormAIn2Result) {
        ui->mAin2_test->setEnabled(true);
        ui->mAin2_test->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingFormAIn2Result) {
        ui->mAin2_test->setEnabled(true);
        ui->mAin2_test->setStyleSheet(
            m_mAIn2TestSuccess ? "background: green; color: white;" :
            m_mAIn2TestSuccess == false && !m_waitingFormAIn2Result ? "background: red; color: white;" :
            "background: blue; color: white;"
        );
    } else {
        ui->mAin2_test->setEnabled(false);
        ui->mAin2_test->setStyleSheet("");
    }

    // HDD test button
    if (m_waitingForHddResult) {
        ui->hdd_test->setEnabled(true);
        ui->hdd_test->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingForHddResult) {
        ui->hdd_test->setEnabled(true);
        ui->hdd_test->setStyleSheet(
            m_hddTestSuccess ? "background: green; color: white;" :
            "background: red; color: white;"
        );
    } else {
        ui->hdd_test->setEnabled(false);
        ui->hdd_test->setStyleSheet("");
    }

    // ===== 光口测试 (pb_test) =====
    if (m_waitingForPbResult) {
        ui->pb_test->setEnabled(true);
        ui->pb_test->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingForPbResult) {
        ui->pb_test->setEnabled(true);
        ui->pb_test->setStyleSheet(
            m_pbTestSuccess ? "background: green; color: white;" :
            "background: red; color: white;"
        );
    } else {
        ui->pb_test->setEnabled(false);
        ui->pb_test->setStyleSheet("");
    }

    // ===== LED 测试 =====
    if (m_waitingForLedResult) {
        ui->led_test->setEnabled(true);
        ui->led_test->setStyleSheet("background: yellow; color: black; font-weight: bold;");
    } else if (initSuccess && !m_waitingForLedResult) {
        ui->led_test->setEnabled(true);
        ui->led_test->setStyleSheet(
            m_ledTestSuccess ? "background: green; color: white;" :
            "background: red; color: white;"
        );
    } else {
        ui->led_test->setEnabled(false);
        ui->led_test->setStyleSheet("");
    }

}

// 测试点击函数（仅设置状态，不立即改色）
void example::on_ddr_test_clicked()
{
    if (!serialPort->isOpen()) return;
    sendCtrlCAndDelay(800);
    serialPort->clear();
    m_recvBuffer.clear();
    m_waitingForDdrResult = true;
    m_ddrTimeoutTimer->start(8000);
    serialPort->write("/userfs/ddr_test\n");
    serialPort->flush();
    updateStatus("DDR 测试中...", example::TestStatus::Running);
    appendLog("DDR 测试: 开始执行", false);
    updateTestButtonsStyle();
}

void example::on_emmc_test_clicked()
{
    if (!serialPort->isOpen()) return;
    sendCtrlCAndDelay(800);
    serialPort->clear();
    m_recvBuffer.clear();
    m_waitingForEmmcResult = true;
    m_emmcTimeoutTimer->start(6000);
    serialPort->write("/userfs/emmc_test\n");
    serialPort->flush();
    updateStatus("eMMC 测试中...", example::TestStatus::Running);
    appendLog("eMMC 测试: 开始执行", false);
    updateTestButtonsStyle();
}

void example::on_rtc_test_clicked()
{
    if (!serialPort->isOpen()) return;
    sendCtrlCAndDelay(800);
    serialPort->clear();
    m_recvBuffer.clear();
    m_waitingForRtcResult = true;
    m_rtcTimeoutTimer->start(10000);
    serialPort->write("/userfs/rtc_test1\n");
    serialPort->flush();
    updateStatus("RTC 测试中...", example::TestStatus::Running);
    appendLog("RTC 测试: 开始执行", false);
    updateTestButtonsStyle();
}

void example::on_wifi_test_clicked()
{
    if (!serialPort->isOpen()) return;

    QMessageBox::information(this, "WiFi 测试提示",
        "请确保已开启以下 WiFi 热点：\n\n"
        "  📶 SSID: AI300\n"
        "  🔐 密码: hanweiai\n\n"
        "设备将尝试连接该热点并测试网络。\n"
        "确认设置正确后，点击 OK 开始测试。",
        QMessageBox::Ok
    );

    sendCtrlCAndDelay(800);
    serialPort->clear();
    m_recvBuffer.clear();
    m_waitingForWifiResult = true;
    m_wifiTimeoutTimer->start(50000);
    serialPort->write("/userfs/wifi_test\n");
    serialPort->flush();
    updateStatus("WiFi 测试中...", example::TestStatus::Running);
    appendLog("WiFi 测试: 正在连接 AI300 并测试网络", false);
    updateTestButtonsStyle();
}

void example::on_output1_test_clicked()
{
    if (!serialPort || !serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开，无法执行 GPIO 测试！");
        return;
    }

    // 设置测试状态
    m_waitingForOutput1Result = true;
    m_output1TimeoutTimer->start(15000); // 5秒超时
    updateTestButtonsStyle();
    updateStatus("GPIO 输出1 测试: 进行中...", example::TestStatus::Running);
    appendLog("GPIO 输出1 测试: 开始交互式测试", false);

    // 创建模态对话框
    QDialog dialog(this);
    dialog.setWindowTitle("GPIO 输出1 测试");
    dialog.setModal(true);

    QVBoxLayout *layout = new QVBoxLayout(&dialog);

    QLabel *label = new QLabel("请按照顺序依次点击下面的按钮：开 和 关\n"
                               "听到继电器“咔哒”声表示动作正常。\n"
                               "测试完成后，请选择结果：");
    label->setWordWrap(true);
    layout->addWidget(label);

    QPushButton *btnOn = new QPushButton("开 (输出高电平)");
    connect(btnOn, &QPushButton::clicked, this, [this]() {
        serialPort->write("/userfs/gpio_out_1.sh 1\n");
        serialPort->flush();
        ui->recvEdit->appendPlainText("[发送] /userfs/gpio_out_1.sh 1");
    });
    layout->addWidget(btnOn);

    QPushButton *btnOff = new QPushButton("关 (输出低电平)");
    connect(btnOff, &QPushButton::clicked, this, [this]() {
        serialPort->write("/userfs/gpio_out_1.sh 0\n");
        serialPort->flush();
        ui->recvEdit->appendPlainText("[发送] /userfs/gpio_out_1.sh 0");
    });
    layout->addWidget(btnOff);

    layout->addSpacing(10);

    QHBoxLayout *resultLayout = new QHBoxLayout();
    QPushButton *btnPass = new QPushButton("✅ 通过");
    QPushButton *btnFail = new QPushButton("❌ 不通过");

    bool result = false;
    connect(btnPass, &QPushButton::clicked, [&dialog, &result]() {
        result = true;
        dialog.accept();
    });
    connect(btnFail, &QPushButton::clicked, [&dialog, &result]() {
        result = false;
        dialog.accept();
    });

    resultLayout->addWidget(btnPass);
    resultLayout->addWidget(btnFail);
    layout->addLayout(resultLayout);

    dialog.exec();

    // 测试结束，更新状态
    m_waitingForOutput1Result = false;
    m_output1TestSuccess = result;
    m_output1TimeoutTimer->stop();

    if (result) {
        updateStatus("GPIO 输出1 测试: 通过 ✅", example::TestStatus::Success);
        appendLog("GPIO 输出1 测试: 通过", true);
    } else {
        updateStatus("GPIO 输出1 测试: 不通过 ❌", example::TestStatus::Failed);
        appendLog("GPIO 输出1 测试: 不通过", false);
    }

    updateTestButtonsStyle(); // 关键：更新按钮颜色
}


void example::on_output2_test_clicked()
{
    if (!serialPort || !serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开，无法执行 GPIO 测试！");
        return;
    }

    // 设置测试状态
    m_waitingForOutput2Result = true;
    m_output2TimeoutTimer->start(15000); // 5秒超时
    updateTestButtonsStyle();
    updateStatus("GPIO 输出2 测试: 进行中...", example::TestStatus::Running);
    appendLog("GPIO 输出2 测试: 开始交互式测试", false);

    // 创建模态对话框
    QDialog dialog(this);
    dialog.setWindowTitle("GPIO 输出2 测试");
    dialog.setModal(true);

    QVBoxLayout *layout = new QVBoxLayout(&dialog);

    QLabel *label = new QLabel("请按照顺序依次点击下面的按钮：开 和 关\n"
                               "听到继电器“咔哒”声表示动作正常。\n"
                               "测试完成后，请选择结果：");
    label->setWordWrap(true);
    layout->addWidget(label);

    QPushButton *btnOn = new QPushButton("开 (输出高电平)");
    connect(btnOn, &QPushButton::clicked, this, [this]() {
        serialPort->write("/userfs/gpio_out_2.sh 1\n");
        serialPort->flush();
        ui->recvEdit->appendPlainText("[发送] /userfs/gpio_out_2.sh 1");
    });
    layout->addWidget(btnOn);

    QPushButton *btnOff = new QPushButton("关 (输出低电平)");
    connect(btnOff, &QPushButton::clicked, this, [this]() {
        serialPort->write("/userfs/gpio_out_2.sh 0\n");
        serialPort->flush();
        ui->recvEdit->appendPlainText("[发送] /userfs/gpio_out_2.sh 0");
    });
    layout->addWidget(btnOff);

    layout->addSpacing(10);

    QHBoxLayout *resultLayout = new QHBoxLayout();
    QPushButton *btnPass = new QPushButton("✅ 通过");
    QPushButton *btnFail = new QPushButton("❌ 不通过");

    bool result = false;
    connect(btnPass, &QPushButton::clicked, [&dialog, &result]() {
        result = true;
        dialog.accept();
    });
    connect(btnFail, &QPushButton::clicked, [&dialog, &result]() {
        result = false;
        dialog.accept();
    });

    resultLayout->addWidget(btnPass);
    resultLayout->addWidget(btnFail);
    layout->addLayout(resultLayout);

    dialog.exec();

    // 测试结束，更新状态
    m_waitingForOutput2Result = false;
    m_output2TestSuccess = result;
    m_output2TimeoutTimer->stop();

    if (result) {
        updateStatus("GPIO 输出2 测试: 通过 ✅", example::TestStatus::Success);
        appendLog("GPIO 输出2 测试: 通过", true);
    } else {
        updateStatus("GPIO 输出2 测试: 不通过 ❌", example::TestStatus::Failed);
        appendLog("GPIO 输出2 测试: 不通过", false);
    }

    updateTestButtonsStyle(); // 关键：更新按钮颜色
}


// ========== 新增：input1 测试逻辑 ==========
void example::on_input1_test_clicked()
{
    // 确认硬件连接
    QMessageBox::StandardButton reply = QMessageBox::question(
        this,
        "干接点-1 输入测试",
        "请确认已正确连接干接点-1测试线（短接或断开对应引脚）。\n"
        "点击“是”开始测试，“否”取消。",
        QMessageBox::Yes | QMessageBox::No
    );
    if (reply == QMessageBox::No) {
        return;
    }

    if (!serialPort || !serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开，无法执行干接点-1输入测试！");
        return;
    }

    // 重置状态
    m_waitingForInput1Result = true;
    m_input1TestSuccess = false; // 未确定，等待结果
    m_recvBuffer.clear();

    // 启动超时定时器（已在构造函数中创建，直接 start）
    m_input1TimeoutTimer->start(5000); // 5秒超时

    // 发送中断并执行测试脚本
    sendCtrlCAndDelay(300);
    QTimer::singleShot(500, this, [this]() {
        serialPort->write("sh /userfs/gpio_in_1.sh\n");
        serialPort->flush();
        ui->recvEdit->appendPlainText("[发送] sh /userfs/gpio_in_1.sh");
        appendLog("干接点-1输入测试: 已启动脚本", true);
        updateStatus("干接点-1输入测试: 等待结果...", example::TestStatus::Running);
    });

    // 立即更新按钮为“进行中”状态
    updateTestButtonsStyle();
}


// ========== 新增：input2 测试逻辑 ==========
void example::on_input2_test_clicked()
{
    // 确认硬件连接
    QMessageBox::StandardButton reply = QMessageBox::question(
        this,
        "干接点-2 输入测试",
        "请确认已正确连接干接点-2测试线（短接或断开对应引脚）。\n"
        "点击“是”开始测试，“否”取消。",
        QMessageBox::Yes | QMessageBox::No
    );
    if (reply == QMessageBox::No) {
        return;
    }

    if (!serialPort || !serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开，无法执行干接点-2输入测试！");
        return;
    }

    // 重置状态
    m_waitingForInput2Result = true;
    m_input2TestSuccess = false; // 未确定，等待结果
    m_recvBuffer.clear();

    // 启动超时定时器（已在构造函数中创建，直接 start）
    m_input2TimeoutTimer->start(5000); // 5秒超时

    // 发送中断并执行测试脚本
    sendCtrlCAndDelay(300);
    QTimer::singleShot(500, this, [this]() {
        serialPort->write("sh /userfs/gpio_in_2.sh\n");
        serialPort->flush();
        ui->recvEdit->appendPlainText("[发送] sh /userfs/gpio_in_2.sh");
        appendLog("干接点-2输入测试: 已启动脚本", true);
        updateStatus("干接点-2输入测试: 等待结果...", example::TestStatus::Running);
    });

    // 立即更新按钮为“进行中”状态
    updateTestButtonsStyle();
}

void example::onUserWaitTimeout()
{
    m_waitSecondsLeft--;
    if (m_waitSecondsLeft >= 0) {
        if (m_waitLabel) {
            m_waitLabel->setText(QString("等待设备返回 \"422-1 测试成功\"...\n%1秒后超时").arg(m_waitSecondsLeft));
        }
    } else {
        // 超时
        m_userTimeoutTimer->stop();
        if (m_waitDialog) {
            m_waitDialog->deleteLater();
            m_waitDialog = nullptr;
        }

        m_422_1TestSuccess = false;
        m_waitingFor422_1Result = false;
        m_422_1TimeoutTimer->stop(); // 停止原有超时

        appendLog("422-1 测试: 等待结果超时（10秒）", false);
        updateStatus("422-1 测试: 超时失败", example::TestStatus::Failed);
        QMessageBox::warning(this, "超时", "10秒内未收到 \"422-1 测试成功\"，测试失败！");
        updateTestButtonsStyle();
    }
}

// ========== 422-1 测试 ==========
void example::on_test1_422_clicked()
{
    QMessageBox::StandardButton reply = QMessageBox::question(
        this, "422-1 测试",
        "请确认已经按照文档正确连接 422-1 的接线。\n点击“是”开始测试，“否”取消。",
        QMessageBox::Yes | QMessageBox::No
        );
    if (reply == QMessageBox::No) return;
    if (!serialPort || !serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开，无法执行 422-1 测试！");
        return;
    }

    m_waitingFor422_1Result = true;
    m_422_1TestSuccess = false;
    m_recvBuffer.clear();
    updateTestButtonsStyle();

    if (m_waitDialog) delete m_waitDialog;
    m_waitDialog = new QDialog(this);
    m_waitDialog->setWindowTitle("422-1 测试中");
    m_waitDialog->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
    m_waitDialog->setModal(false);
    m_waitLabel = new QLabel("等待设备返回 \"422-1 测试成功\"... 10秒后超时", m_waitDialog);
    QVBoxLayout *layout = new QVBoxLayout(m_waitDialog);
    layout->addWidget(m_waitLabel);
    m_waitDialog->setLayout(layout);
    m_waitDialog->resize(380, 80);

    if (!m_userTimeoutTimer) m_userTimeoutTimer = new QTimer(this);
    m_userTimeoutTimer->disconnect();
    connect(m_userTimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitDialog) { m_waitDialog->deleteLater(); m_waitDialog = nullptr; }
        if (m_countdownTimer) { m_countdownTimer->stop(); m_countdownTimer->deleteLater(); m_countdownTimer = nullptr; }
        m_waitingFor422_1Result = false;
        m_422_1TestSuccess = false;
        appendLog("422-1 测试: 等待结果超时（10秒）", false);
        updateStatus("422-1 测试: 超时失败 ❌", example::TestStatus::Failed);
        QMessageBox::warning(this, "超时", "10秒内未收到 \"422-1 测试成功\"，测试失败！");
        updateTestButtonsStyle();
    });
    m_userTimeoutTimer->setSingleShot(true);
    m_userTimeoutTimer->start(10000);

    if (!m_countdownTimer) m_countdownTimer = new QTimer(this);
    m_countdownTimer->disconnect();
    m_remainingSeconds = 10;
    connect(m_countdownTimer, &QTimer::timeout, this, [this]() {
        m_remainingSeconds--;
        if (m_waitLabel) {
            m_waitLabel->setText(QString("等待设备返回 \"422-1 测试成功\"... %1秒后超时").arg(m_remainingSeconds));
        }
        if (m_remainingSeconds <= 0) m_countdownTimer->stop();
    });
    m_countdownTimer->start(1000);

    m_waitDialog->show();

    sendCtrlCAndDelay(300);
    QTimer::singleShot(500, this, [this]() {
        serialPort->write("/userfs/422-1\n");
        serialPort->flush();
        ui->recvEdit->appendPlainText("[发送] /userfs/422_1");
        appendLog("422-1 测试: 已启动", true);
        updateStatus("422-1 测试: 等待结果...", example::TestStatus::Running);
    });
}


void example::onUserWaitTimeout1()
{
    m_waitSecondsLeft--;
    if (m_waitSecondsLeft >= 0) {
        if (m_waitLabel) {
            m_waitLabel->setText(QString("等待设备返回 \"422-2 测试成功\"...\n%1秒后超时").arg(m_waitSecondsLeft));
        }
    } else {
        // 超时
        m_userTimeoutTimer->stop();
        if (m_waitDialog) {
            m_waitDialog->deleteLater();
            m_waitDialog = nullptr;
        }

        m_422_2TestSuccess = false;
        m_waitingFor422_2Result = false;
        m_422_2TimeoutTimer->stop(); // 停止原有超时

        appendLog("422-2 测试: 等待结果超时（10秒）", false);
        updateStatus("422-2 测试: 超时失败", example::TestStatus::Failed);
        QMessageBox::warning(this, "超时", "10秒内未收到 \"422-2 测试成功\"，测试失败！");
        updateTestButtonsStyle(); // ← 🔥 添加这一行！
    }
}


// ========== 422-2 测试 ==========
void example::on_test2_422_clicked()
{
    QMessageBox::StandardButton reply = QMessageBox::question(
        this, "422-2 测试",
        "请确认已经按照文档正确连接 422-2 的接线。\n点击“是”开始测试，“否”取消。",
        QMessageBox::Yes | QMessageBox::No
        );
    if (reply == QMessageBox::No) return;
    if (!serialPort || !serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开，无法执行 422-2 测试！");
        return;
    }

    m_waitingFor422_2Result = true;
    m_422_2TestSuccess = false;
    m_recvBuffer.clear();
    updateTestButtonsStyle();

    if (m_waitDialog) delete m_waitDialog;
    m_waitDialog = new QDialog(this);
    m_waitDialog->setWindowTitle("422-2 测试中");
    m_waitDialog->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
    m_waitDialog->setModal(false);
    m_waitLabel = new QLabel("等待设备返回 \"422-2 测试成功\"... 10秒后超时", m_waitDialog);
    QVBoxLayout *layout = new QVBoxLayout(m_waitDialog);
    layout->addWidget(m_waitLabel);
    m_waitDialog->setLayout(layout);
    m_waitDialog->resize(380, 80);

    if (!m_userTimeoutTimer) m_userTimeoutTimer = new QTimer(this);
    m_userTimeoutTimer->disconnect();
    connect(m_userTimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitDialog) { m_waitDialog->deleteLater(); m_waitDialog = nullptr; }
        if (m_countdownTimer) { m_countdownTimer->stop(); m_countdownTimer->deleteLater(); m_countdownTimer = nullptr; }
        m_waitingFor422_2Result = false;
        m_422_2TestSuccess = false;
        appendLog("422-2 测试: 等待结果超时（10秒）", false);
        updateStatus("422-2 测试: 超时失败 ❌", example::TestStatus::Failed);
        QMessageBox::warning(this, "超时", "10秒内未收到 \"422-2 测试成功\"，测试失败！");
        updateTestButtonsStyle();
    });
    m_userTimeoutTimer->setSingleShot(true);
    m_userTimeoutTimer->start(10000);

    if (!m_countdownTimer) m_countdownTimer = new QTimer(this);
    m_countdownTimer->disconnect();
    m_remainingSeconds = 10;
    connect(m_countdownTimer, &QTimer::timeout, this, [this]() {
        m_remainingSeconds--;
        if (m_waitLabel) {
            m_waitLabel->setText(QString("等待设备返回 \"422-2 测试成功\"... %1秒后超时").arg(m_remainingSeconds));
        }
        if (m_remainingSeconds <= 0) m_countdownTimer->stop();
    });
    m_countdownTimer->start(1000);

    m_waitDialog->show();

    sendCtrlCAndDelay(300);
    QTimer::singleShot(500, this, [this]() {
        serialPort->write("/userfs/422-2\n");
        serialPort->flush();
        ui->recvEdit->appendPlainText("[发送] /userfs/422_2");
        appendLog("422-2 测试: 已启动", true);
        updateStatus("422-2 测试: 等待结果...", example::TestStatus::Running);
    });
}


void example::onUserWaitTimeout_485_1()
{
    m_waitSecondsLeft--;
    if (m_waitSecondsLeft >= 0) {
        if (m_waitLabel) {
            m_waitLabel->setText(QString("等待设备返回 \"485-1 测试成功\"...\n%1秒后超时").arg(m_waitSecondsLeft));
        }
    } else {
        m_userTimeoutTimer->stop();
        if (m_waitDialog) {
            m_waitDialog->deleteLater();
            m_waitDialog = nullptr;
        }

        m_485_1TestSuccess = false;
        m_waitingFor485_1Result = false;
        if (m_485_1TimeoutTimer) m_485_1TimeoutTimer->stop();

        appendLog("485-1 测试: 等待结果超时（10秒）", false);
        updateStatus("485-1 测试: 超时失败 ❌", example::TestStatus::Failed);
        QMessageBox::warning(this, "超时", "10秒内未收到 \"485-1 测试成功\"，测试失败！");
        updateTestButtonsStyle();
    }
}

void example::onUserWaitTimeout_485_2()
{
    m_waitSecondsLeft--;
    if (m_waitSecondsLeft >= 0) {
        if (m_waitLabel) {
            m_waitLabel->setText(QString("等待设备返回 \"485-2 测试成功\"...\n%1秒后超时").arg(m_waitSecondsLeft));
        }
    } else {
        m_userTimeoutTimer->stop();
        if (m_waitDialog) {
            m_waitDialog->deleteLater();
            m_waitDialog = nullptr;
        }

        m_485_2TestSuccess = false;
        m_waitingFor485_2Result = false;
        if (m_485_2TimeoutTimer) m_485_2TimeoutTimer->stop();

        appendLog("485-2 测试: 等待结果超时（10秒）", false);
        updateStatus("485-2 测试: 超时失败 ❌", example::TestStatus::Failed);
        QMessageBox::warning(this, "超时", "10秒内未收到 \"485-2 测试成功\"，测试失败！");
        updateTestButtonsStyle();
    }
}

void example::onUserWaitTimeout_485_3()
{
    m_waitSecondsLeft--;
    if (m_waitSecondsLeft >= 0) {
        if (m_waitLabel) {
            m_waitLabel->setText(QString("等待设备返回 \"485-3 测试成功\"...\n%1秒后超时").arg(m_waitSecondsLeft));
        }
    } else {
        m_userTimeoutTimer->stop();
        if (m_waitDialog) {
            m_waitDialog->deleteLater();
            m_waitDialog = nullptr;
        }

        m_485_3TestSuccess = false;
        m_waitingFor485_3Result = false;
        if (m_485_3TimeoutTimer) m_485_3TimeoutTimer->stop();

        appendLog("485-3 测试: 等待结果超时（10秒）", false);
        updateStatus("485-3 测试: 超时失败 ❌", example::TestStatus::Failed);
        QMessageBox::warning(this, "超时", "10秒内未收到 \"485-3 测试成功\"，测试失败！");
        updateTestButtonsStyle();
    }
}

void example::onUserWaitTimeout_485_4()
{
    m_waitSecondsLeft--;
    if (m_waitSecondsLeft >= 0) {
        if (m_waitLabel) {
            m_waitLabel->setText(QString("等待设备返回 \"485-4 测试成功\"...\n%1秒后超时").arg(m_waitSecondsLeft));
        }
    } else {
        m_userTimeoutTimer->stop();
        if (m_waitDialog) {
            m_waitDialog->deleteLater();
            m_waitDialog = nullptr;
        }

        m_485_4TestSuccess = false;
        m_waitingFor485_4Result = false;
        if (m_485_4TimeoutTimer) m_485_4TimeoutTimer->stop();

        appendLog("485-4 测试: 等待结果超时（10秒）", false);
        updateStatus("485-4 测试: 超时失败 ❌", example::TestStatus::Failed);
        QMessageBox::warning(this, "超时", "10秒内未收到 \"485-4 测试成功\"，测试失败！");
        updateTestButtonsStyle();
    }
}

void example::sendStringToSerialPort(const QString &portName, const QByteArray &data)
{
    QSerialPort tempPort;
    tempPort.setPortName(portName);
    tempPort.setBaudRate(QSerialPort::Baud115200);
    tempPort.setDataBits(QSerialPort::Data8);
    tempPort.setParity(QSerialPort::NoParity);
    tempPort.setStopBits(QSerialPort::OneStop);
    tempPort.setFlowControl(QSerialPort::NoFlowControl);

    if (!tempPort.open(QIODevice::WriteOnly)) {
        appendLog(QString("无法打开串口 %1 发送数据").arg(portName), false);
        return;
    }

    tempPort.write(data);
    tempPort.waitForBytesWritten(1000);
    tempPort.close();

    appendLog(QString("已通过 %1 发送: %2").arg(portName, QString::fromLatin1(data)), true);
}

// ========== 485-1 测试 ==========
void example::on_test1_485_clicked()
{
    QMessageBox::StandardButton reply = QMessageBox::question(
        this, "485-1 测试",
        "请确认已经按照文档正确连接 485-1 的接线。\n点击“是”开始测试，“否”取消。",
        QMessageBox::Yes | QMessageBox::No
        );
    if (reply == QMessageBox::No) return;
    if (!serialPort || !serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开，无法执行 485-1 测试！");
        return;
    }

    m_waitingFor485_1Result = true;
    m_485_1TestSuccess = false;
    m_recvBuffer.clear();
    updateTestButtonsStyle();

    if (m_waitDialog) delete m_waitDialog;
    m_waitDialog = new QDialog(this);
    m_waitDialog->setWindowTitle("485-1 测试中");
    m_waitDialog->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
    m_waitDialog->setModal(false);
    m_waitLabel = new QLabel("等待设备返回 \"485-1 测试成功\"... 10秒后超时", m_waitDialog);
    QVBoxLayout *layout = new QVBoxLayout(m_waitDialog);
    layout->addWidget(m_waitLabel);
    m_waitDialog->setLayout(layout);
    m_waitDialog->resize(380, 80);

    // 超时定时器（10秒）
    if (!m_userTimeoutTimer) m_userTimeoutTimer = new QTimer(this);
    m_userTimeoutTimer->disconnect();
    connect(m_userTimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitDialog) { m_waitDialog->deleteLater(); m_waitDialog = nullptr; }
        if (m_countdownTimer) { m_countdownTimer->stop(); m_countdownTimer->deleteLater(); m_countdownTimer = nullptr; }
        m_waitingFor485_1Result = false;
        m_485_1TestSuccess = false;
        appendLog("485-1 测试: 等待结果超时（10秒）", false);
        updateStatus("485-1 测试: 超时失败 ❌", example::TestStatus::Failed);
        QMessageBox::warning(this, "超时", "10秒内未收到 \"485-1 测试成功\"，测试失败！");
        updateTestButtonsStyle();
    });
    m_userTimeoutTimer->setSingleShot(true);
    m_userTimeoutTimer->start(10000);

    // 倒计时更新（每1秒）
    if (!m_countdownTimer) m_countdownTimer = new QTimer(this);
    m_countdownTimer->disconnect();
    m_remainingSeconds = 10;
    connect(m_countdownTimer, &QTimer::timeout, this, [this]() {
        m_remainingSeconds--;
        if (m_waitLabel) {
            m_waitLabel->setText(QString("等待设备返回 \"485-1 测试成功\"... %1秒后超时").arg(m_remainingSeconds));
        }
        if (m_remainingSeconds <= 0) m_countdownTimer->stop();
    });
    m_countdownTimer->start(1000);

    m_waitDialog->show();

    sendCtrlCAndDelay(300);
    QTimer::singleShot(500, this, [this]() {
        serialPort->write("/userfs/485_1\n");
        serialPort->flush();
        ui->recvEdit->appendPlainText("[发送] /userfs/485_1");
        appendLog("485-1 测试: 已启动", true);
        updateStatus("485-1 测试: 等待结果...", example::TestStatus::Running);
    });
}

// ========== 485-2 测试 ==========
void example::on_test2_485_clicked()
{
    QMessageBox::StandardButton reply = QMessageBox::question(
        this, "485-2 测试",
        "请确认已经按照文档正确连接 485-2 的接线。\n点击“是”开始测试，“否”取消。",
        QMessageBox::Yes | QMessageBox::No
        );
    if (reply == QMessageBox::No) return;
    if (!serialPort || !serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开，无法执行 485-2 测试！");
        return;
    }

    m_waitingFor485_2Result = true;
    m_485_2TestSuccess = false;
    m_recvBuffer.clear();
    updateTestButtonsStyle();

    if (m_waitDialog) delete m_waitDialog;
    m_waitDialog = new QDialog(this);
    m_waitDialog->setWindowTitle("485-2 测试中");
    m_waitDialog->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
    m_waitDialog->setModal(false);
    m_waitLabel = new QLabel("等待设备返回 \"485-2 测试成功\"... 10秒后超时", m_waitDialog);
    QVBoxLayout *layout = new QVBoxLayout(m_waitDialog);
    layout->addWidget(m_waitLabel);
    m_waitDialog->setLayout(layout);
    m_waitDialog->resize(380, 80);

    if (!m_userTimeoutTimer) m_userTimeoutTimer = new QTimer(this);
    m_userTimeoutTimer->disconnect();
    connect(m_userTimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitDialog) { m_waitDialog->deleteLater(); m_waitDialog = nullptr; }
        if (m_countdownTimer) { m_countdownTimer->stop(); m_countdownTimer->deleteLater(); m_countdownTimer = nullptr; }
        m_waitingFor485_2Result = false;
        m_485_2TestSuccess = false;
        appendLog("485-2 测试: 等待结果超时（10秒）", false);
        updateStatus("485-2 测试: 超时失败 ❌", example::TestStatus::Failed);
        QMessageBox::warning(this, "超时", "10秒内未收到 \"485-2 测试成功\"，测试失败！");
        updateTestButtonsStyle();
    });
    m_userTimeoutTimer->setSingleShot(true);
    m_userTimeoutTimer->start(10000);

    if (!m_countdownTimer) m_countdownTimer = new QTimer(this);
    m_countdownTimer->disconnect();
    m_remainingSeconds = 10;
    connect(m_countdownTimer, &QTimer::timeout, this, [this]() {
        m_remainingSeconds--;
        if (m_waitLabel) {
            m_waitLabel->setText(QString("等待设备返回 \"485-2 测试成功\"... %1秒后超时").arg(m_remainingSeconds));
        }
        if (m_remainingSeconds <= 0) m_countdownTimer->stop();
    });
    m_countdownTimer->start(1000);

    m_waitDialog->show();

    sendCtrlCAndDelay(300);
    QTimer::singleShot(500, this, [this]() {
        serialPort->write("/userfs/485_2\n");
        serialPort->flush();
        ui->recvEdit->appendPlainText("[发送] /userfs/485_2");
        appendLog("485-2 测试: 已启动", true);
        updateStatus("485-2 测试: 等待结果...", example::TestStatus::Running);
    });
}

// ========== 485-3 测试 ==========
void example::on_test3_485_clicked()
{
    QMessageBox::StandardButton reply = QMessageBox::question(
        this, "485-3 测试",
        "请确认已经按照文档正确连接 485-3 的接线。\n点击“是”开始测试，“否”取消。",
        QMessageBox::Yes | QMessageBox::No
        );
    if (reply == QMessageBox::No) return;
    if (!serialPort || !serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开，无法执行 485-3 测试！");
        return;
    }

    m_waitingFor485_3Result = true;
    m_485_3TestSuccess = false;
    m_recvBuffer.clear();
    updateTestButtonsStyle();

    if (m_waitDialog) delete m_waitDialog;
    m_waitDialog = new QDialog(this);
    m_waitDialog->setWindowTitle("485-3 测试中");
    m_waitDialog->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
    m_waitDialog->setModal(false);
    m_waitLabel = new QLabel("等待设备返回 \"485-3 测试成功\"... 10秒后超时", m_waitDialog);
    QVBoxLayout *layout = new QVBoxLayout(m_waitDialog);
    layout->addWidget(m_waitLabel);
    m_waitDialog->setLayout(layout);
    m_waitDialog->resize(380, 80);

    if (!m_userTimeoutTimer) m_userTimeoutTimer = new QTimer(this);
    m_userTimeoutTimer->disconnect();
    connect(m_userTimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitDialog) { m_waitDialog->deleteLater(); m_waitDialog = nullptr; }
        if (m_countdownTimer) { m_countdownTimer->stop(); m_countdownTimer->deleteLater(); m_countdownTimer = nullptr; }
        m_waitingFor485_3Result = false;
        m_485_3TestSuccess = false;
        appendLog("485-3 测试: 等待结果超时（10秒）", false);
        updateStatus("485-3 测试: 超时失败 ❌", example::TestStatus::Failed);
        QMessageBox::warning(this, "超时", "10秒内未收到 \"485-3 测试成功\"，测试失败！");
        updateTestButtonsStyle();
    });
    m_userTimeoutTimer->setSingleShot(true);
    m_userTimeoutTimer->start(10000);

    if (!m_countdownTimer) m_countdownTimer = new QTimer(this);
    m_countdownTimer->disconnect();
    m_remainingSeconds = 10;
    connect(m_countdownTimer, &QTimer::timeout, this, [this]() {
        m_remainingSeconds--;
        if (m_waitLabel) {
            m_waitLabel->setText(QString("等待设备返回 \"485-3 测试成功\"... %1秒后超时").arg(m_remainingSeconds));
        }
        if (m_remainingSeconds <= 0) m_countdownTimer->stop();
    });
    m_countdownTimer->start(1000);

    m_waitDialog->show();

    sendCtrlCAndDelay(300);
    QTimer::singleShot(500, this, [this]() {
        serialPort->write("/userfs/485_3\n");
        serialPort->flush();
        ui->recvEdit->appendPlainText("[发送] /userfs/485_3");
        appendLog("485-3 测试: 已启动", true);
        updateStatus("485-3 测试: 等待结果...", example::TestStatus::Running);
    });
}

// ========== 485-4 测试 ==========
void example::on_test4_485_clicked()
{
    QMessageBox::StandardButton reply = QMessageBox::question(
        this, "485-4 测试",
        "请确认已经按照文档正确连接 485-4 的接线。\n点击“是”开始测试，“否”取消。",
        QMessageBox::Yes | QMessageBox::No
        );
    if (reply == QMessageBox::No) return;
    if (!serialPort || !serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开，无法执行 485-4 测试！");
        return;
    }

    m_waitingFor485_4Result = true;
    m_485_4TestSuccess = false;
    m_recvBuffer.clear();
    updateTestButtonsStyle();

    if (m_waitDialog) delete m_waitDialog;
    m_waitDialog = new QDialog(this);
    m_waitDialog->setWindowTitle("485-4 测试中");
    m_waitDialog->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
    m_waitDialog->setModal(false);
    m_waitLabel = new QLabel("等待设备返回 \"485-4 测试成功\"... 10秒后超时", m_waitDialog);
    QVBoxLayout *layout = new QVBoxLayout(m_waitDialog);
    layout->addWidget(m_waitLabel);
    m_waitDialog->setLayout(layout);
    m_waitDialog->resize(380, 80);

    if (!m_userTimeoutTimer) m_userTimeoutTimer = new QTimer(this);
    m_userTimeoutTimer->disconnect();
    connect(m_userTimeoutTimer, &QTimer::timeout, this, [this]() {
        if (m_waitDialog) { m_waitDialog->deleteLater(); m_waitDialog = nullptr; }
        if (m_countdownTimer) { m_countdownTimer->stop(); m_countdownTimer->deleteLater(); m_countdownTimer = nullptr; }
        m_waitingFor485_4Result = false;
        m_485_4TestSuccess = false;
        appendLog("485-4 测试: 等待结果超时（10秒）", false);
        updateStatus("485-4 测试: 超时失败 ❌", example::TestStatus::Failed);
        QMessageBox::warning(this, "超时", "10秒内未收到 \"485-4 测试成功\"，测试失败！");
        updateTestButtonsStyle();
    });
    m_userTimeoutTimer->setSingleShot(true);
    m_userTimeoutTimer->start(10000);

    if (!m_countdownTimer) m_countdownTimer = new QTimer(this);
    m_countdownTimer->disconnect();
    m_remainingSeconds = 10;
    connect(m_countdownTimer, &QTimer::timeout, this, [this]() {
        m_remainingSeconds--;
        if (m_waitLabel) {
            m_waitLabel->setText(QString("等待设备返回 \"485-4 测试成功\"... %1秒后超时").arg(m_remainingSeconds));
        }
        if (m_remainingSeconds <= 0) m_countdownTimer->stop();
    });
    m_countdownTimer->start(1000);

    m_waitDialog->show();

    sendCtrlCAndDelay(300);
    QTimer::singleShot(500, this, [this]() {
        serialPort->write("/userfs/485_4\n");
        serialPort->flush();
        ui->recvEdit->appendPlainText("[发送] /userfs/485_4");
        appendLog("485-4 测试: 已启动", true);
        updateStatus("485-4 测试: 等待结果...", example::TestStatus::Running);
    });
}

//网口按钮功能
void example::on_test1_eth_clicked()
{
    if (!serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开！");
        return;
    }

    QMessageBox::StandardButton reply = QMessageBox::question(
        this, "网口1测试", "请确认网线是否插好！\n点击“是”开始测试。",
        QMessageBox::Yes | QMessageBox::No
    );
    if (reply != QMessageBox::Yes) {
        return;
    }
    sendCtrlCAndDelay(500);
    serialPort->clear();

    m_waitingForEth1Result = true;
    m_recvBuffer.clear();
    updateStatus("网口1测试: 进行中...", example::TestStatus::Running);
    appendLog("网口1测试: 已发送测试命令", true);

    serialPort->write("/userfs/eth1_test\n");
    ui->recvEdit->appendPlainText("[发送] /userfs/eth1_test");

    m_eth1TimeoutTimer->start(20000); // 20秒超时
    updateTestButtonsStyle();
}

void example::on_test2_eth_clicked()
{
    if (!serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开！");
        return;
    }

    QMessageBox::StandardButton reply = QMessageBox::question(
        this, "网口2测试", "请确认网线是否插好！\n点击“是”开始测试。",
        QMessageBox::Yes | QMessageBox::No
    );
    if (reply != QMessageBox::Yes) {
        return;
    }

    sendCtrlCAndDelay(500);
    serialPort->clear();

    m_waitingForEth2Result = true;
    m_recvBuffer.clear();
    updateStatus("网口2测试: 进行中...", example::TestStatus::Running);
    appendLog("网口2测试: 已发送测试命令", true);

    serialPort->write("/userfs/eth2_test\n");
    ui->recvEdit->appendPlainText("[发送] /userfs/eth2_test");

    m_eth2TimeoutTimer->start(20000);
    updateTestButtonsStyle();
}

void example::on_test3_eth_clicked()
{
    if (!serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开！");
        return;
    }

    QMessageBox::StandardButton reply = QMessageBox::question(
        this, "网口3测试", "请确认网线是否插好！\n点击“是”开始测试。",
        QMessageBox::Yes | QMessageBox::No
    );
    if (reply != QMessageBox::Yes) {
        return;
    }

    sendCtrlCAndDelay(500);
    serialPort->clear();

    m_waitingForEth3Result = true;
    m_recvBuffer.clear();
    updateStatus("网口3测试: 进行中...", example::TestStatus::Running);
    appendLog("网口3测试: 已发送测试命令", true);

    serialPort->write("/userfs/eth3_test\n");
    ui->recvEdit->appendPlainText("[发送] /userfs/eth3_test");

    m_eth3TimeoutTimer->start(20000);
    updateTestButtonsStyle();
}

void example::on_test4_eth_clicked()
{
    if (!serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开！");
        return;
    }

    QMessageBox::StandardButton reply = QMessageBox::question(
        this, "网口4测试", "请确认网线是否插好！\n点击“是”开始测试。",
        QMessageBox::Yes | QMessageBox::No
    );
    if (reply != QMessageBox::Yes) {
        return;
    }

    sendCtrlCAndDelay(500);
    serialPort->clear();

    m_waitingForEth4Result = true;
    m_recvBuffer.clear();
    updateStatus("网口4测试: 进行中...", example::TestStatus::Running);
    appendLog("网口4测试: 已发送测试命令", true);

    serialPort->write("/userfs/eth4_test\n");
    ui->recvEdit->appendPlainText("[发送] /userfs/eth4_test");

    m_eth4TimeoutTimer->start(20000);
    updateTestButtonsStyle();
}

void example::on_test5_eth_clicked()
{
    if (!serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开！");
        return;
    }

    QMessageBox::StandardButton reply = QMessageBox::question(
        this, "网口5测试", "请确认网线是否插好！\n点击“是”开始测试。",
        QMessageBox::Yes | QMessageBox::No
    );
    if (reply != QMessageBox::Yes) {
        return;
    }

    sendCtrlCAndDelay(500);
    serialPort->clear();

    m_waitingForEth5Result = true;
    m_recvBuffer.clear();
    updateStatus("网口5测试: 进行中...", example::TestStatus::Running);
    appendLog("网口5测试: 已发送测试命令", true);

    serialPort->write("/userfs/eth5_test\n");
    ui->recvEdit->appendPlainText("[发送] /userfs/eth5_test");

    m_eth5TimeoutTimer->start(20000);
    updateTestButtonsStyle();
}


//4g
void example::on_test_4g_clicked()
{
    if (!serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开！");
        return;
    }
    sendCtrlCAndDelay(500);

    // 直接开始测试（无弹窗）
    m_waitingFor4gResult = true;
    m_recvBuffer.clear();
    updateStatus("4G测试: 进行中...", example::TestStatus::Running);
    appendLog("4G测试: 已发送测试命令", true);

    serialPort->write("/userfs/4g_test\n");
    serialPort->flush();
    ui->recvEdit->appendPlainText("[发送] /userfs/4g_test");

    // 启动超时定时器（30秒，因4G拨号较慢）
    m_4gTimeoutTimer->start(35000);

    updateTestButtonsStyle();
}

//usb
void example::on_usb_test_clicked()
{
    if (!serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开！");
        return;
    }

    // 弹窗提示用户插入设备
    QMessageBox::StandardButton reply = QMessageBox::question(
        this,
        "USB 测试",
        "请插入 USB-sd卡设备，插入后点击 Yes！",
        QMessageBox::Yes | QMessageBox::No
    );

    if (reply != QMessageBox::Yes) {
        appendLog("USB测试: 用户取消", false);
        return;
    }

    sendCtrlCAndDelay(500);
    serialPort->clear();
    m_recvBuffer.clear();

    // 开始测试（通过串口发送命令）
    m_waitingForUsbResult = true;
    m_recvBuffer.clear();
    updateStatus("USB测试: 进行中...", example::TestStatus::Running);
    appendLog("USB测试: 已发送 /userfs/usbhost_test", true);

    serialPort->write("/userfs/usbhost_test\n");
    ui->recvEdit->appendPlainText("[发送] /userfs/usbhost_test");

    // 启动超时定时器（60秒，因USB检测可能较慢）
    m_usbTimeoutTimer->start(25000);

    updateTestButtonsStyle();
}

// mA 输出1 测试
void example::on_mAoutput1_test_clicked()
{
    if (!serialPort || !serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开，无法执行 mA 输出1 测试！");
        return;
    }

    // 设置为“进行中”状态（黄色）
    m_waitingFormaOutput1Result = true;
    updateTestButtonsStyle();
    updateStatus("GPIO ma输出1 测试: 进行中...", example::TestStatus::Running);
    appendLog("GPIO ma输出1 测试: 开始交互式测试", false);

    // 发送测试脚本，触发设备输出电流
    serialPort->write("/userfs/mAgpio_out_1.sh\n");
    serialPort->flush();
    ui->recvEdit->appendPlainText("[发送] /userfs/mAgpio_out_1.sh");
    appendLog("mA 输出1 测试: 已启动脚本", true);

    // 弹窗提示用户使用万用表测量
    QMessageBox msgBox1(this);
    msgBox1.setWindowTitle("mA 输出1 测试");
    msgBox1.setText("请使用万用表进行电流测试。\n观察电流表，若满足规格请点“通过”，否则点“不通过”。");
    msgBox1.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
    msgBox1.button(QMessageBox::Yes)->setText("通过");
    msgBox1.button(QMessageBox::No)->setText("不通过");
    QMessageBox::StandardButton reply = static_cast<QMessageBox::StandardButton>(msgBox1.exec());

    // ✅ 关键修复：测试结束，不再等待！
    m_waitingFormaOutput1Result = false;

    // 记录用户判断结果
    m_mAoutput1TestSuccess = (reply == QMessageBox::Yes);
    m_recvBuffer.clear(); // 清空接收缓冲区（保持风格一致）

    // 更新最终状态和日志
    if (m_mAoutput1TestSuccess) {
        updateStatus("mA 输出1 测试: 通过", example::TestStatus::Success);
        appendLog("mA 输出1 测试: 用户确认通过", true);
    } else {
        updateStatus("mA 输出1 测试: 未通过", example::TestStatus::Failed);
        appendLog("mA 输出1 测试: 用户确认未通过", false);
    }

    // 刷新按钮样式（此时会显示绿色或红色）
    updateTestButtonsStyle();
}

// mA 输出2 测试
void example::on_mAoutput2_test_clicked()
{
    if (!serialPort || !serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开，无法执行 mA 输出2 测试！");
        return;
    }

    // 设置为“进行中”状态（黄色）
    m_waitingFormaOutput2Result = true;
    updateTestButtonsStyle();
    updateStatus("GPIO ma输出2 测试: 进行中...", example::TestStatus::Running);
    appendLog("GPIO ma输出2 测试: 开始交互式测试", false);

    // 发送测试脚本
    serialPort->write("/userfs/mAgpio_out_2.sh\n");
    serialPort->flush();
    ui->recvEdit->appendPlainText("[发送] /userfs/mAgpio_out_2.sh");
    appendLog("mA 输出2 测试: 已启动脚本", true);

    // 弹窗提示用户测量
    QMessageBox msgBox2(this);
    msgBox2.setWindowTitle("mA 输出2 测试");
    msgBox2.setText("请使用万用表进行电流测试。\n观察电流表，若满足规格请点“通过”，否则点“不通过”。");
    msgBox2.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
    msgBox2.button(QMessageBox::Yes)->setText("通过");
    msgBox2.button(QMessageBox::No)->setText("不通过");
    QMessageBox::StandardButton reply = static_cast<QMessageBox::StandardButton>(msgBox2.exec());

    // ✅ 关键修复：测试结束，不再等待！
    m_waitingFormaOutput2Result = false;

    // 记录结果
    m_mAoutput2TestSuccess = (reply == QMessageBox::Yes);
    m_recvBuffer.clear();

    if (m_mAoutput2TestSuccess) {
        updateStatus("mA 输出2 测试: 通过", example::TestStatus::Success);
        appendLog("mA 输出2 测试: 用户确认通过", true);
    } else {
        updateStatus("mA 输出2 测试: 未通过", example::TestStatus::Failed);
        appendLog("mA 输出2 测试: 用户确认未通过", false);
    }

    updateTestButtonsStyle();
}


//4-20 in
void example::on_mAin1_test_clicked()
{
    // 弹出确认对话框
    QMessageBox::StandardButton reply = QMessageBox::question(
        this,
        "请连接硬件",
        "请正确连接4-20mA输入1的杜邦线。\n确认连接完成后，点击“是”继续测试。",
        QMessageBox::Yes | QMessageBox::No,
        QMessageBox::No
    );

    if (reply != QMessageBox::Yes) {
        appendLog("用户取消了 4-20mA输入1测试", false);
        return;
    }

    if (!serialPort->isOpen()) {
        appendLog("串口未打开，无法执行 mA输入1测试", false);
        return;
    }

    sendCtrlCAndDelay(500);
    serialPort->clear();
    m_recvBuffer.clear();

    // 重置状态
    m_waitingFormAIn1Result = true;
    m_mAIn1TestSuccess = false; // 重置结果
    m_waitingFormAIn2Result = false; // 互斥

    m_mAIn1TimeoutTimer->start(15000);

    updateStatus("4-20mA输入1测试中...", example::TestStatus::Running);
    appendLog("开始执行 4-20mA输入1测试（脚本自动5次采样）", true);

    serialPort->write("/userfs/mAin_test1.sh\n");
    serialPort->flush();

    updateTestButtonsStyle();
}


void example::on_mAin2_test_clicked()
{
    // 弹出确认对话框
    QMessageBox::StandardButton reply = QMessageBox::question(
        this,
        "请连接硬件",
        "请正确连接4-20mA输入2的杜邦线。\n确认连接完成后，点击“是”继续测试.",
        QMessageBox::Yes | QMessageBox::No,
        QMessageBox::No
    );

    if (reply != QMessageBox::Yes) {
        appendLog("用户取消了 4-20mA输入2测试", false);
        return;
    }

    if (!serialPort->isOpen()) {
        appendLog("串口未打开，无法执行 mA输入2测试", false);
        return;
    }

    sendCtrlCAndDelay(500);
    serialPort->clear();
    m_recvBuffer.clear();

    // 重置状态
    m_waitingFormAIn2Result = true;
    m_mAIn2TestSuccess = false; // 重置结果
    m_waitingFormAIn1Result = false; // 互斥

    m_mAIn2TimeoutTimer->start(15000);

    updateStatus("4-20mA输入2测试中...", example::TestStatus::Running);
    appendLog("开始执行 4-20mA输入2测试（脚本自动5次采样）", true);

    serialPort->write("/userfs/mAin_test2.sh\n");
    serialPort->flush();

    updateTestButtonsStyle();
}

//hdd
void example::on_hdd_test_clicked()
{
    // 弹出确认对话框（可选，但建议保留一致性）
    QMessageBox::StandardButton reply = QMessageBox::question(
        this,
        "请确认硬件",
        "请确保已插入存储设备。\n确认后点击“是”开始 HDD 测试。",
        QMessageBox::Yes | QMessageBox::No,
        QMessageBox::No
    );

    if (reply != QMessageBox::Yes) {
        appendLog("用户取消了 HDD 测试", false);
        return;
    }

    if (!serialPort->isOpen()) {
        appendLog("串口未打开，无法执行 HDD 测试", false);
        return;
    }

    sendCtrlCAndDelay(500);
    serialPort->clear();
    m_recvBuffer.clear();

    // 重置状态（HDD 无互斥，但保持风格一致）
    m_waitingForHddResult = true;
    m_hddTestSuccess = false;

    m_hddTimeoutTimer->start(15000); // 15秒超时

    updateStatus("HDD测试中...", example::TestStatus::Running);
    appendLog("开始执行 HDD 测试（/userfs/hdd.sh）", true);

    serialPort->write("/userfs/hdd.sh\n");
    serialPort->flush();

    updateTestButtonsStyle();
}

//cat---pb_test
void example::on_pb_test_clicked()
{
    if (!serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开！");
        return;
    }

    QMessageBox::StandardButton reply = QMessageBox::question(
        this,
        "光口测试",
        "光口测试请确认光口是否已经正确连接？\n点击“是”开始测试。",
        QMessageBox::Yes | QMessageBox::No,
        QMessageBox::No
    );
    if (reply != QMessageBox::Yes) {
        appendLog("用户取消了光口测试", false);
        return;
    }

    // 清理缓冲区，发送 Ctrl+C 确保干净环境（建议加上，与 mAIn/ETH 一致）
    sendCtrlCAndDelay(500);
    serialPort->clear();
    m_recvBuffer.clear();

    // 设置状态
    m_waitingForPbResult = true;
    m_pbTestSuccess = false;

    updateStatus("光口测试: 进行中...", example::TestStatus::Running);
    appendLog("光口测试: 已发送测试命令 /userfs/pb_test", true);

    serialPort->write("/userfs/pb_test\n");
    serialPort->flush();  // 确保立即发送

    // 启动超时定时器（15秒）
    m_pbTimeoutTimer->start(20000);

    updateTestButtonsStyle();
}

//led_test
void example::on_led_test_clicked()
{
    if (!serialPort || !serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开，无法执行 LED 测试！");
        return;
    }

    sendCtrlCAndDelay(500);
    serialPort->clear();
    m_recvBuffer.clear();

    // 设置“进行中”状态（黄色）
    m_waitingForLedResult = true;
    updateTestButtonsStyle();
    updateStatus("LED 测试: 进行中...", example::TestStatus::Running);
    appendLog("LED 测试: 开始交互式测试", false);

    // 发送 LED 脚本
    serialPort->write("/userfs/led.sh\n");
    serialPort->flush();
    ui->recvEdit->appendPlainText("[发送] /userfs/led.sh");
    appendLog("LED 测试: 已启动脚本 /userfs/led.sh", true);

    // 弹窗提示用户观察
    QMessageBox msgBox3(this);
    msgBox3.setWindowTitle("LED 测试");
    msgBox3.setText("请观察 LED 闪烁状态。\n若满足要求请点击“通过”，否则点击“不通过”。");
    msgBox3.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
    msgBox3.button(QMessageBox::Yes)->setText("通过");
    msgBox3.button(QMessageBox::No)->setText("不通过");
    msgBox3.setDefaultButton(QMessageBox::No); // 对应原来的 QMessageBox::No 作为默认
    QMessageBox::StandardButton reply = static_cast<QMessageBox::StandardButton>(msgBox3.exec());

    // ✅ 测试结束：不再等待
    m_waitingForLedResult = false;

    // 记录用户判断结果
    m_ledTestSuccess = (reply == QMessageBox::Yes);
    m_recvBuffer.clear(); // 保持风格一致

    // 更新最终状态
    if (m_ledTestSuccess) {
        updateStatus("LED 测试: 通过", example::TestStatus::Success);
        appendLog("LED 测试: 用户确认通过", true);
    } else {
        updateStatus("LED 测试: 未通过", example::TestStatus::Failed);
        appendLog("LED 测试: 用户确认未通过", false);
    }

    //在用户确认后，自动发送 Ctrl+C 终止脚本，避免设备端持续闪烁：
    sendCtrlCAndDelay(300); // 发送 Ctrl+C 停止 led.sh

    // 刷新按钮样式
    updateTestButtonsStyle();
}


//writeSnBtn写入设备编号
void example::on_writeSnBtn_clicked()
{
    if (!serialPort || !serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开，无法写入SN！");
        return;
    }

    // 弹出输入框
    bool ok;
    QString suffix = QInputDialog::getText(
        this,
        "输入gas设备编号后两位",
        "请输入gas设备编号的最后两位数字（001~500）：",
        QLineEdit::Normal,
        "000",
        &ok
    );

    if (!ok || suffix.isEmpty()) {
        appendLog("用户取消了SN写入操作", false);
        return;
    }

    int num = suffix.toInt(&ok);
    if (!ok || num < 1 || num > 500) {
        QMessageBox::warning(this, "输入错误", "请输入 001 到 500 之间的有效编号！");
        return;
    }

    QString fullSn = QString("046d4b0524100%1").arg(num, 3, 10, QChar('0'));

    // 二次确认
    if (QMessageBox::question(this, "确认写入",
        QString("即将写入gas设备编号：<b>%1</b><br>请确认设备已连接且可写！").arg(fullSn),
        QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
        appendLog("用户取消写入 SN: " + fullSn, false);
        return;
    }

    // 清空缓冲区，避免历史数据干扰
    m_recvBuffer.clear();

    // 设置状态
    m_currentSnToWrite = fullSn;
    m_waitingForSnWrite = true;
    m_snWriteSuccess = false;

    // 启动超时定时器（5秒）
    if (!m_snWriteTimeoutTimer) {
        m_snWriteTimeoutTimer = new QTimer(this);
        connect(m_snWriteTimeoutTimer, &QTimer::timeout, this, [this]() {
            if (m_waitingForSnWrite) {
                m_waitingForSnWrite = false;
                updateStatus("SN写入: 超时 ❌", TestStatus::Failed);
                appendLog("SN写入超时（5秒）", false);
                updateTestButtonsStyle();
            }
        });
    }
    m_snWriteTimeoutTimer->start(5000);

    // 发送 Ctrl+C 确保干净环境
    sendCtrlCAndDelay(300);

    // 发送写入命令
    QString cmd = QString("/userfs/write_sn.sh %1\n").arg(fullSn);
    serialPort->write(cmd.toUtf8());
    serialPort->flush();
    ui->recvEdit->appendPlainText("[发送] " + cmd.trimmed());
    appendLog("开始写入设备编号: " + fullSn, true);
}


//writeSnBtn写入设备编号
void example::on_writeSnBtn1_clicked()
{
    if (!serialPort || !serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开，无法写入SN！");
        return;
    }

    // 弹出输入框
    bool ok;
    QString suffix = QInputDialog::getText(
        this,
        "输入nvr设备编号后两位",
        "请输入nvr设备编号的最后两位数字（001~500）：",
        QLineEdit::Normal,
        "000",
        &ok
    );

    if (!ok || suffix.isEmpty()) {
        appendLog("用户取消了SN写入操作", false);
        return;
    }

    int num = suffix.toInt(&ok);
    if (!ok || num < 1 || num > 500) {
        QMessageBox::warning(this, "输入错误", "请输入 001 到 500 之间的有效编号！");
        return;
    }

    QString fullSn = QString("046e4b0524200%1").arg(num, 3, 10, QChar('0'));

    // 二次确认
    if (QMessageBox::question(this, "确认写入",
        QString("即将写入nvr设备编号：<b>%1</b><br>请确认设备已连接且可写！").arg(fullSn),
        QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
        appendLog("用户取消写入 SN: " + fullSn, false);
        return;
    }

    // 清空缓冲区，避免历史数据干扰
    m_recvBuffer.clear();

    // 设置状态
    m_currentSn1ToWrite = fullSn;
    m_waitingForSn1Write = true;
    m_snWrite1Success = false;

    // 启动超时定时器（5秒）
    if (!m_snWrite1TimeoutTimer) {
        m_snWrite1TimeoutTimer = new QTimer(this);
        connect(m_snWrite1TimeoutTimer, &QTimer::timeout, this, [this]() {
            if (m_waitingForSn1Write) {
                m_waitingForSn1Write = false;
                updateStatus("SN写入: 超时 ❌", TestStatus::Failed);
                appendLog("SN写入超时（5秒）", false);
                updateTestButtonsStyle();
            }
        });
    }
    m_snWrite1TimeoutTimer->start(5000);

    // 发送 Ctrl+C 确保干净环境
    sendCtrlCAndDelay(300);

    // 发送写入命令
    QString cmd = QString("/userfs/write_sn.sh %1\n").arg(fullSn);
    serialPort->write(cmd.toUtf8());
    serialPort->flush();
    ui->recvEdit->appendPlainText("[发送] " + cmd.trimmed());
    appendLog("开始写入设备编号: " + fullSn, true);
}


//all
void example::on_summaryBtn_clicked()
{
    if (!serialPort || !serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开！");
        return;
    }

    serialPort->flush();
    m_recvBuffer.clear();
    sendCtrlCAndDelay(300);

    // 1. 收集所有测试项的状态
    QStringList successList, failList;

    struct TestItem { QString name; bool success; };
    QList<TestItem> tests = {
        {"DDR测试", m_ddrTestSuccess},
        {"eMMC测试", m_emmcTestSuccess},
        {"RTC测试", m_rtcTestSuccess},
        {"Wi-Fi测试", m_wifiTestSuccess},
        {"输出1", m_output1TestSuccess},
        {"输出2", m_output2TestSuccess},
        {"mA输出1", m_mAoutput1TestSuccess},   // ← 新增
        {"mA输出2", m_mAoutput2TestSuccess},   // ← 新增
        {"mA输入1", m_mAIn1TestSuccess},   // ← 新增
        {"mA输入2", m_mAIn2TestSuccess},   // ← 新增
        {"HDD测试", m_hddTestSuccess},   // ← 新增
        {"输入1", m_input1TestSuccess},
        {"输入2", m_input2TestSuccess},
        {"422-1", m_422_1TestSuccess},
        {"422-2", m_422_2TestSuccess},
        {"485-1", m_485_1TestSuccess},
        {"485-2", m_485_2TestSuccess},
        {"485-3", m_485_3TestSuccess},
        {"485-4", m_485_4TestSuccess},
        {"网口1", m_eth1TestSuccess},
        {"网口2", m_eth2TestSuccess},
        {"网口3", m_eth3TestSuccess},
        {"网口4", m_eth4TestSuccess},
        {"网口5", m_eth5TestSuccess},
        {"光口测试", m_pbTestSuccess},   // ← 新增
        {"LED测试", m_ledTestSuccess},   // ← 新增
        {"4G测试", m_4gTestSuccess},
        {"USB测试", m_usbTestSuccess}
    };

    for (const auto& t : tests) {
        if (t.success) {
            successList << t.name;
        } else {
            failList << t.name;
        }
    }

    int successCount = successList.size();
    int failCount = failList.size();

    // 2. 构造美观的报告内容
    QString content = "【测试汇总报告】\n";
    content += QString("┌───────────────\n");
    content += QString("│ 成功: %1 项\n").arg(successCount);
    content += QString("│ 失败: %1 项\n").arg(failCount);
    content += QString("└───────────────\n\n");

    if (!successList.isEmpty()) {
        content += "✔ 成功项：\n";
        for (const QString& item : successList) {
            content += QString("  • %1\n").arg(item);
        }
        content += "\n";
    }

    if (!failList.isEmpty()) {
        content += "✘ 失败项：\n";
        for (const QString& item : failList) {
            content += QString("  • %1\n").arg(item);
        }
        content += "\n";
    }

    content += "生成时间：" + QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss") + "\n";

    // 3. 转义并构造 shell 命令
    QString escapedContent = content
        .replace("\\", "\\\\")
        .replace("\"", "\\\"")
        .replace("\n", "\\n");

    QString cmd = QString(
//        "mkdir -p /userfs && "
        "echo -e \"%1\" > /userfs/new_all.txt && "
        "cat /userfs/new_all.txt"
    ).arg(escapedContent);

    // 4. 设置状态并发送
    m_waitingForSummaryResult = true;
    m_summaryBuffer.clear();

    // 安全删除旧定时器
    if (m_summaryTimeoutTimer) {
        m_summaryTimeoutTimer->stop();
        m_summaryTimeoutTimer->deleteLater();
        m_summaryTimeoutTimer = nullptr;
    }

    m_summaryTimeoutTimer = new QTimer(this);
    connect(m_summaryTimeoutTimer, &QTimer::timeout, this, [this]() {
        m_waitingForSummaryResult = false;

        QString report = m_summaryBuffer.trimmed();
        QString separator = QString(50, '=');

        // 构造最终显示内容（带边框）
        QString displayText = "\n" + separator + "\n"
                              "        【测试汇总报告】\n"
                              + separator + "\n"
                              + report + "\n"
                              + separator;

        ui->logEdit->append(displayText);

        // 可选：自动滚动到底部
        QScrollBar *vbar = ui->logEdit->verticalScrollBar();
        if (vbar) vbar->setValue(vbar->maximum());

        sleep(1);
        serialPort->write("sync\n");
        serialPort->flush();
        appendLog("汇总报告已生成并显示", true);
        updateStatus("汇总报告生成完成", example::TestStatus::Success);

        // 清理定时器
        if (m_summaryTimeoutTimer) {
            m_summaryTimeoutTimer->deleteLater();
            m_summaryTimeoutTimer = nullptr;
        }
    });

    m_summaryTimeoutTimer->setSingleShot(true);
    m_summaryTimeoutTimer->start(10000); // 10秒超时

    serialPort->write(cmd.toUtf8());
    serialPort->flush();
    updateStatus("正在生成汇总报告...", example::TestStatus::Running);
    appendLog("正在生成汇总报告并保存至 /userfs/new_all.txt...", true);
}


//查询测试结果
void example::on_showReportBtn_clicked()
{
    if (!serialPort || !serialPort->isOpen()) {
        QMessageBox::warning(this, "警告", "串口未打开！");
        return;
    }

    // 清空日志框
    ui->logEdit->clear();

    // 设置状态
    m_waitingForShowReport = true;
    m_showReportBuffer.clear();

    // 清理旧定时器
    if (m_showReportTimeoutTimer) {
        m_showReportTimeoutTimer->stop();
        m_showReportTimeoutTimer->deleteLater();
        m_showReportTimeoutTimer = nullptr;
    }

    // 创建新定时器
    m_showReportTimeoutTimer = new QTimer(this);
    connect(m_showReportTimeoutTimer, &QTimer::timeout, this, [this]() {
        m_waitingForShowReport = false;

        QString content = m_showReportBuffer.trimmed();

        if (content.isEmpty()) {
            ui->logEdit->append("❌ 未获取到报告内容（文件可能不存在）");
        } else {
            QString sep = QString(60, '=');
            QString title = "        📄 来自设备的测试汇总报告";
            QString display = "\n" + sep + "\n" + title + "\n" + sep + "\n"
                            + content + "\n" + sep + "\n";

            ui->logEdit->append(display);
            updateStatus("测试汇总报告显示完成", example::TestStatus::Success);

            // 自动滚动到底部
            auto vbar = ui->logEdit->verticalScrollBar();
            if (vbar) vbar->setValue(vbar->maximum());
        }

        // 清理定时器
        if (m_showReportTimeoutTimer) {
            m_showReportTimeoutTimer->deleteLater();
            m_showReportTimeoutTimer = nullptr;
        }
    });
    //test--ctrl+c
//    m_recvBuffer.clear();
//    sendCtrlCAndDelay(300);

    serialPort->write("sync\n");
    serialPort->flush();

    m_showReportTimeoutTimer->setSingleShot(true);
    m_showReportTimeoutTimer->start(5000); // 5秒超时（报告较小，无需10秒）

    // 发送命令读取文件
    serialPort->write("cat /userfs/new_all.txt\n");
    serialPort->flush();
    updateStatus("正在从设备读取...", example::TestStatus::Running);
    appendLog("正在从设备读取 /userfs/new_all.txt ...", true);
}





// 日志操作
void example::on_saveLogBtn_clicked()
{
    QString fileName = QFileDialog::getSaveFileName(
        this, "保存日志文件",
        "test_log_" + QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss") + ".txt",
        "文本文件 (*.txt);;所有文件 (*)"
    );
    if (fileName.isEmpty()) return;

    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QMessageBox::critical(this, "错误", "无法创建文件：" + file.errorString());
        return;
    }

    QTextStream out(&file);
    out.setCodec("UTF-8");
    out << ui->logEdit->toPlainText();
    file.close();

    QMessageBox::information(this, "成功", "日志已保存到：\n" + fileName);
    appendLog("日志已保存至: " + fileName.split("/").last(), true);
}

void example::on_loadLogBtn_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(
        this, "选择日志文件", ".", "文本文件 (*.txt);;所有文件 (*)"
    );
    if (fileName.isEmpty()) return;

    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QMessageBox::warning(this, "错误", "无法打开文件：" + file.errorString());
        return;
    }

    QTextStream in(&file);
    in.setCodec("UTF-8");
    QString content = in.readAll();
    file.close();

    ui->logEdit->clear();
    ui->logEdit->setPlainText(content);
    appendLog("已加载历史日志: " + fileName.split("/").last(), true);
}

void example::on_clearLogBtn_clicked()
{
    ui->logEdit->clear();
}

void example::sendCtrlCAndDelay(int ms)
{
    if (serialPort->isOpen()) {
        serialPort->write("\x03");
        serialPort->flush();
        ui->recvEdit->appendPlainText("[发送] Ctrl+C (中断)");
    }
    if (ms > 0) {
        QThread::msleep(ms);
        QApplication::processEvents();
    }
}

void example::resetAllTestStates()
{
    // 停止所有定时器
    if (m_rtcTimeoutTimer) m_rtcTimeoutTimer->stop();
    if (m_ddrTimeoutTimer) m_ddrTimeoutTimer->stop();
    if (m_emmcTimeoutTimer) m_emmcTimeoutTimer->stop();
    if (m_wifiTimeoutTimer) m_wifiTimeoutTimer->stop();
    if (m_output1TimeoutTimer) m_output1TimeoutTimer->stop();
    if (m_output2TimeoutTimer) m_output2TimeoutTimer->stop();
    if (m_input1TimeoutTimer) m_input1TimeoutTimer->stop();
    if (m_input2TimeoutTimer) m_input2TimeoutTimer->stop();
    if (m_422_1TimeoutTimer) m_422_1TimeoutTimer->stop();
    if (m_422_2TimeoutTimer) m_422_2TimeoutTimer->stop();
    if (m_485_1TimeoutTimer) m_485_1TimeoutTimer->stop();
    if (m_485_2TimeoutTimer) m_485_2TimeoutTimer->stop();
    if (m_485_3TimeoutTimer) m_485_3TimeoutTimer->stop();
    if (m_485_4TimeoutTimer) m_485_4TimeoutTimer->stop();
    if (m_eth1TimeoutTimer) m_eth1TimeoutTimer->stop();
    if (m_eth2TimeoutTimer) m_eth2TimeoutTimer->stop();
    if (m_eth3TimeoutTimer) m_eth3TimeoutTimer->stop();
    if (m_eth4TimeoutTimer) m_eth4TimeoutTimer->stop();
    if (m_eth5TimeoutTimer) m_eth5TimeoutTimer->stop();
    if (m_4gTimeoutTimer) m_4gTimeoutTimer->stop();
    if (m_usbTimeoutTimer) m_usbTimeoutTimer->stop();
    if (m_mAIn1TimeoutTimer) m_mAIn1TimeoutTimer->stop();
    if (m_mAIn2TimeoutTimer) m_mAIn2TimeoutTimer->stop();
    if (m_hddTimeoutTimer) m_hddTimeoutTimer->stop();
    if (m_pbTimeoutTimer) m_pbTimeoutTimer->stop();





    // 重置所有等待标志
    m_waitingForInitSuccess = false;
    m_waitingForDdrResult = false;
    m_waitingForEmmcResult = false;
    m_waitingForRtcResult = false;
    m_waitingForWifiResult = false;
    m_waitingForOutput1Result = false;
    m_waitingForOutput2Result = false;
    m_waitingForInput1Result = false;
    m_waitingForInput2Result = false;
    m_waitingFor422_1Result = false;
    m_waitingFor422_2Result = false;
    m_waitingFor485_1Result = false;
    m_waitingFor485_2Result = false;
    m_waitingFor485_3Result = false;
    m_waitingFor485_4Result = false;
    m_waitingForEth1Result = false;
    m_waitingForEth2Result = false;
    m_waitingForEth3Result = false;
    m_waitingForEth4Result = false;
    m_waitingForEth5Result = false;
    m_waitingFor4gResult = false;
    m_waitingForUsbResult = false;

    m_waitingFormaOutput1Result = false;
    m_waitingFormaOutput2Result = false;

    m_waitingFormAIn1Result = false;
    m_waitingFormAIn2Result = false;

    m_waitingForHddResult = false;
    m_waitingForPbResult = false;

    // 重置 LED 测试状态
    m_waitingForLedResult = false;



    // 重置测试结果（关键：清除 ✅/❌ 状态）
    m_ddrTestSuccess = false;
    m_emmcTestSuccess = false;
    m_rtcTestSuccess = false;
    m_wifiTestSuccess = false;
    m_output1TestSuccess = false;
    m_output2TestSuccess = false;
    m_input1TestSuccess = false;
    m_input2TestSuccess = false;
    m_422_1TestSuccess = false;
    m_422_2TestSuccess = false;
    m_485_1TestSuccess = false;
    m_485_2TestSuccess = false;
    m_485_3TestSuccess = false;
    m_485_4TestSuccess = false;
    m_eth1TestSuccess = false;
    m_eth2TestSuccess = false;
    m_eth3TestSuccess = false;
    m_eth4TestSuccess = false;
    m_eth5TestSuccess = false;
    m_4gTestSuccess = false;
    m_usbTestSuccess = false;
    // 重置 mA 输出测试结果
    m_mAoutput1TestSuccess = false;
    m_mAoutput2TestSuccess = false;

    m_mAIn1TestSuccess = false;
    m_mAIn2TestSuccess = false;

    m_hddTestSuccess = false;
    m_pbTestSuccess = false;

    m_ledTestSuccess = false;


    // 新增：重置汇总状态
    m_waitingForSummaryResult = false;
    m_summaryBuffer.clear();
    if (m_summaryTimeoutTimer) {
       m_summaryTimeoutTimer->stop();
       m_summaryTimeoutTimer->deleteLater();
       m_summaryTimeoutTimer = nullptr;
    }

    // 新增：重置显示状态
    m_waitingForShowReport = false;
    m_showReportBuffer.clear();
    if (m_showReportTimeoutTimer) {
       m_showReportTimeoutTimer->stop();
       m_showReportTimeoutTimer->deleteLater();
       m_showReportTimeoutTimer = nullptr;
    }


    // 清空接收缓冲区
    m_recvBuffer.clear();

    // 更新按钮样式（变为蓝色可用）
    updateTestButtonsStyle();
}





/*无关*/
//切换页面
void example::on_switchBt_clicked()
{
    if (!m_secondWindow) {
        m_secondWindow = new SecondWindow(nullptr); // ← parent = nullptr！独立窗口
        connect(m_secondWindow, &SecondWindow::backRequested, this, [this]() {
            this->show();  // 重新显示主窗口
        });
    }
    m_secondWindow->show();
    this->hide();
}

//定时器
void example::on_timerBt_clicked()
{
    if (!m_timer) {
        m_timer = new timer(nullptr); // ← parent = nullptr！独立窗口
        connect(m_timer, &timer::backRequested, this, [this]() {
            this->show();  // 重新显示主窗口
        });
    }
    m_timer->show();
    this->hide();
}


//设备信息
void example::on_devInfo_clicked()
{
    if (!m_devInfo) {
        m_devInfo = new FormDevInfo(nullptr); // ← parent = nullptr！独立窗口
        connect(m_devInfo, &FormDevInfo::backRequested, this, [this]() {
            this->show();  // 重新显示主窗口
        });
    }
    m_devInfo->show();
    this->hide();
}

//设备日志
void example::on_devLog_clicked()
{
    if (!m_devLog) {
        m_devLog = new FormDevLOG(nullptr); // ← parent = nullptr！独立窗口
        connect(m_devLog, &FormDevLOG::backRequested, this, [this]() {
            this->show();  // 重新显示主窗口
        });
    }
    m_devLog->show();
    this->hide();
}

// 主窗口中
//void example::on_serialBt_clicked()
//{
//    static serial *s_serialWindow = nullptr; // 或作为成员变量
//    if (!s_serialWindow) {
//        s_serialWindow = new serial(nullptr); // parent = nullptr → 独立
//        s_serialWindow->setAttribute(Qt::WA_DeleteOnClose);
//    }
//    s_serialWindow->show();
//    s_serialWindow->raise();
//    s_serialWindow->activateWindow();
//    // 不 hide 主窗口 → 共存！
//}

void example::on_serialBt_clicked()
{
    serial *win = new serial(nullptr);
    win->setAttribute(Qt::WA_DeleteOnClose); // 关闭时自动 delete
    win->show();
    win->raise();
    win->activateWindow();
}


void example::promptUserForResult(bool& successFlag, const QString& testName)
{
    // 停止所有定时器
    if (m_userTimeoutTimer) {
        m_userTimeoutTimer->stop();
        m_userTimeoutTimer->disconnect();
    }
    if (m_countdownTimer) {
        m_countdownTimer->stop();
        m_countdownTimer->deleteLater();
        m_countdownTimer = nullptr;
    }

    // 关闭等待浮窗
    if (m_waitDialog) {
        m_waitDialog->deleteLater();
        m_waitDialog = nullptr;
    }

    // 弹出人工确认对话框
    QMessageBox msgBox(this);
    msgBox.setWindowTitle(testName + " - 人工确认");
    msgBox.setText("设备已返回 \"测试成功\"。\n\n"
                   "请检查交互助手回显中是否包含 \"ai300\"。\n"
                   "若包含，请点击【通过】；否则点击【不通过】。");
    msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
    msgBox.button(QMessageBox::Yes)->setText("通过");
    msgBox.button(QMessageBox::No)->setText("不通过");
    successFlag = (msgBox.exec() == QMessageBox::Yes);

    // 更新状态和日志
    updateStatus(testName + (successFlag ? ": 通过 ✅" : ": 不通过 ❌"),
                 successFlag ? example::TestStatus::Success : example::TestStatus::Failed);
    appendLog(testName + ": 用户确认 " + (successFlag ? "通过" : "不通过"), successFlag);
    updateTestButtonsStyle();

    // 清理并终止脚本
    m_recvBuffer.clear();
    sendCtrlCAndDelay(300);
}
